प्रोजेक्ट जो मैं काम कर रहा हूं (नोड.जेएस) का तात्पर्य है कि फाइल सिस्टम (कॉपी / रीडिंग / राइटिंग आदि) के साथ बहुत सारे ऑपरेशन। मैं जानना चाहता हूं कि कौन सी विधियां सबसे तेज हैं, और मुझे एक सलाह मिलने में खुशी होगी। धन्यवाद।
प्रोजेक्ट जो मैं काम कर रहा हूं (नोड.जेएस) का तात्पर्य है कि फाइल सिस्टम (कॉपी / रीडिंग / राइटिंग आदि) के साथ बहुत सारे ऑपरेशन। मैं जानना चाहता हूं कि कौन सी विधियां सबसे तेज हैं, और मुझे एक सलाह मिलने में खुशी होगी। धन्यवाद।
जवाबों:
धाराओं का उपयोग करके कोड की एक पंक्ति में फ़ाइल कॉपी करने का यह एक अच्छा तरीका है:
var fs = require('fs');
fs.createReadStream('test.log').pipe(fs.createWriteStream('newLog.log'));
नोड v8.5.0 में, copyFile जोड़ा गया था
const fs = require('fs');
// destination.txt will be created or overwritten by default.
fs.copyFile('source.txt', 'destination.txt', (err) => {
if (err) throw err;
console.log('source.txt was copied to destination.txt');
});
createReadStream
और createWriteStream
त्रुटियों के लिए दोनों की जांच करना चाहते हैं, इसलिए आपको एक-लाइनर नहीं मिलेगा (हालांकि यह अभी भी उतना ही तेज़ होगा)।
cp test.log newLog.log
माध्यम से निष्पादित करने की तुलना में यह कितना तेज / धीमा है require('child_process').exec
?
copy
से विंडो पर पोर्टेबल नहीं है, एक पूर्ण Node.js समाधान के विपरीत।
child_process.execFile('/bin/cp', ['--no-target-directory', source, target])
।
fs.createReadStream('./init/xxx.json').pipe(fs.createWriteStream('xxx.json'));
एक ही तंत्र, लेकिन यह त्रुटि हैंडलिंग जोड़ता है:
function copyFile(source, target, cb) {
var cbCalled = false;
var rd = fs.createReadStream(source);
rd.on("error", function(err) {
done(err);
});
var wr = fs.createWriteStream(target);
wr.on("error", function(err) {
done(err);
});
wr.on("close", function(ex) {
done();
});
rd.pipe(wr);
function done(err) {
if (!cbCalled) {
cb(err);
cbCalled = true;
}
}
}
WriteStream
वसीयत में एक त्रुटि केवल इसे मिटा देगी। आपको rd.destroy()
खुद को बुलाना होगा । कम से कम मेरे साथ तो यही हुआ। अफसोस की बात है कि सोर्स कोड को छोड़कर ज्यादा डॉक्यूमेंटेशन नहीं है।
cb
खड़ा है? तीसरे तर्क के रूप में हमें क्या करना चाहिए?
मैं createReadStream/createWriteStream
किसी कारण से काम करने की विधि प्राप्त करने में सक्षम नहीं था , लेकिन fs-extra
एनपीएम मॉड्यूल का उपयोग करके इसने तुरंत काम किया। मैं हालांकि प्रदर्शन अंतर के बारे में निश्चित नहीं हूं।
npm install --save fs-extra
var fs = require('fs-extra');
fs.copySync(path.resolve(__dirname,'./init/xxx.json'), 'xxx.json');
fs.copy(src, dst, callback);
, और इन्हें @ mvillar की चिंता का समाधान करना चाहिए।
Node.js 8.5.0 के बाद से हमारे पास नई fs.copyFile और fs.copyFileSync विधियाँ हैं।
उपयोग उदाहरण:
var fs = require('fs');
// destination.txt will be created or overwritten by default.
fs.copyFile('source.txt', 'destination.txt', (err) => {
if (err) throw err;
console.log('source.txt was copied to destination.txt');
});
copyFile()
लंबी फाइलों को अधिलेखित करते समय यह खराब हो गया है। uv_fs_copyfile()
Node v8.7.0 (libuv 1.15.0) तक के सौजन्य से । देखिए github.com/libuv/libuv/pull/1552
वादा और त्रुटि प्रबंधन के साथ लिखने के लिए तेजी से और उपयोग करने में सुविधाजनक।
function copyFile(source, target) {
var rd = fs.createReadStream(source);
var wr = fs.createWriteStream(target);
return new Promise(function(resolve, reject) {
rd.on('error', reject);
wr.on('error', reject);
wr.on('finish', resolve);
rd.pipe(wr);
}).catch(function(error) {
rd.destroy();
wr.end();
throw error;
});
}
एसिंक्स / वेट सिंटैक्स के साथ भी:
async function copyFile(source, target) {
var rd = fs.createReadStream(source);
var wr = fs.createWriteStream(target);
try {
return await new Promise(function(resolve, reject) {
rd.on('error', reject);
wr.on('error', reject);
wr.on('finish', resolve);
rd.pipe(wr);
});
} catch (error) {
rd.destroy();
wr.end();
throw error;
}
}
new Promise(function(resolve, reject) { resolve(1); resolve(2); reject(3); reject(4); console.log("DONE"); }).then(console.log.bind(console), function(e){console.log("E", e);});
और इस पर युक्ति को देखा और आप सही हैं: हल किए गए वादे को हल करने या अस्वीकार करने का प्रयास करने का कोई प्रभाव नहीं पड़ता है। शायद आप अपना जवाब बढ़ा सकते हैं और समझा सकते हैं कि आपने फ़ंक्शन को इस तरह क्यों लिखा है? धन्यवाद :-)
close
होना चाहिए finish
।
/dev/stdin
, तो यह बग github.com/joyent/node/issues/25375
खैर, आमतौर पर अतुल्यकालिक फ़ाइल संचालन से बचना अच्छा है। यहां संक्षिप्त (यानी कोई त्रुटि से निपटने) सिंक उदाहरण है:
var fs = require('fs');
fs.writeFileSync(targetFile, fs.readFileSync(sourceFile));
*Sync
विधियों का उपयोग करना पूरी तरह से नोड्ज की दार्शनिकता के खिलाफ है! मुझे भी लगता है कि वे धीरे-धीरे पदावनत हो रहे हैं। नोडज का पूरा विचार यह है कि यह सिंगल थ्रेडेड और ईवेंट-चालित है।
त्रुटि घटना हैंडलर के लिए शॉर्ट-कट के साथ माइक शिलिंग का समाधान।
function copyFile(source, target, cb) {
var cbCalled = false;
var rd = fs.createReadStream(source);
rd.on("error", done);
var wr = fs.createWriteStream(target);
wr.on("error", done);
wr.on("close", function(ex) {
done();
});
rd.pipe(wr);
function done(err) {
if (!cbCalled) {
cb(err);
cbCalled = true;
}
}
}
अगर आपको इसके बारे में कोई चिंता नहीं है, तो यह असेंबली होने के नाते नहीं है, और गीगाबाइट-आकार की फ़ाइलों की प्रतिलिपि नहीं बना रहे हैं, और केवल एक फ़ंक्शन के लिए एक और निर्भरता नहीं जोड़ेंगे:
function copySync(src, dest) {
var data = fs.readFileSync(src);
fs.writeFileSync(dest, data);
}
fs.existsSync
कॉल छोड़ देना चाहिए। fs.existsSync
कॉल और कॉल के बीच समय में फ़ाइल गायब हो सकती है fs.readFileSync
, जिसका अर्थ है कि fs.existsSync
कॉल हमें किसी भी चीज़ से बचाता नहीं है।
false
यदि fs.existsSync
असफल होने की संभावना है , तो वापसी करना खराब एर्गोनॉमिक्स है, क्योंकि कुछ उपभोक्ताओं के copySync
लिए हर बार रिटर्न मूल्य का निरीक्षण करने के बारे में सोचना होगा, जिसे हम fs.writeFileSync
एट अल के लिए करते हैं । । अपवाद फेंकना वास्तव में बेहतर है।
const fs = require("fs");
fs.copyFileSync("filepath1", "filepath2"); //fs.copyFileSync("file1.txt", "file2.txt");
यह वह है जो मैं व्यक्तिगत रूप से एक फ़ाइल की प्रतिलिपि बनाने के लिए उपयोग करता हूं और नोड.जेएस का उपयोग करके किसी अन्य फ़ाइल को प्रतिस्थापित करता हूं :)
तेज प्रतियों के लिए आपको fs.constants.COPYFILE_FICLONE
ध्वज का उपयोग करना चाहिए । यह (फाइलसिस्टम के लिए जो इसका समर्थन करता है) अनुमति देता है वास्तव में फाइल की सामग्री की नकल नहीं करने के लिए। बस एक नई फ़ाइल प्रविष्टि बनाई गई है, लेकिन यह स्रोत फ़ाइल के कॉपी-ऑन-राइट "क्लोन" की ओर इशारा करती है।
कुछ नहीं करने के लिए / कुछ करने का सबसे तेज़ तरीका है;)
https://nodejs.org/api/fs.html#fs_fs_copyfile_src_dest_flags_callback
let fs = require("fs");
fs.copyFile(
"source.txt",
"destination.txt",
fs.constants.COPYFILE_FICLONE,
(err) => {
if (err) {
// TODO: handle error
console.log("error");
}
console.log("success");
}
);
इसके बजाय वादों का उपयोग करना:
let fs = require("fs");
let util = require("util");
let copyFile = util.promisify(fs.copyFile);
copyFile(
"source.txt",
"destination.txt",
fs.constants.COPYFILE_FICLONE
)
.catch(() => console.log("error"))
.then(() => console.log("success"));
fs.promises.copyFile
कॉपी से पहले फ़ाइल के दृश्य की जाँच का बेवॉच समाधान:
function copy(from, to) {
return new Promise(function (resolve, reject) {
fs.access(from, fs.F_OK, function (error) {
if (error) {
reject(error);
} else {
var inputStream = fs.createReadStream(from);
var outputStream = fs.createWriteStream(to);
function rejectCleanup(error) {
inputStream.destroy();
outputStream.end();
reject(error);
}
inputStream.on('error', rejectCleanup);
outputStream.on('error', rejectCleanup);
outputStream.on('finish', resolve);
inputStream.pipe(outputStream);
}
});
});
}
कॉपी फ़ंक्शन में निर्मित नोडज का उपयोग क्यों नहीं किया जाता है?
यह दोनों async और सिंक संस्करण प्रदान करते हैं:
const fs = require('fs');
// destination.txt will be created or overwritten by default.
fs.copyFile('source.txt', 'destination.txt', (err) => {
if (err) throw err;
console.log('source.txt was copied to destination.txt');
});
https://nodejs.org/api/fs.html#fs_fs_copyfilesync_src_dest_flags
माइक का हल , लेकिन वादों के साथ:
const FileSystem = require('fs');
exports.copyFile = function copyFile(source, target) {
return new Promise((resolve,reject) => {
const rd = FileSystem.createReadStream(source);
rd.on('error', err => reject(err));
const wr = FileSystem.createWriteStream(target);
wr.on('error', err => reject(err));
wr.on('close', () => resolve());
rd.pipe(wr);
});
};
एक अन्य उत्तर का सुधार।
विशेषताएं:
promise
, जो एक बड़ी परियोजना में उपयोग करना आसान बनाता है।उपयोग:
var onePromise = copyFilePromise("src.txt", "dst.txt");
var anotherPromise = copyMultiFilePromise(new Array(new Array("src1.txt", "dst1.txt"), new Array("src2.txt", "dst2.txt")));
कोड:
function copyFile(source, target, cb) {
console.log("CopyFile", source, target);
var ensureDirectoryExistence = function (filePath) {
var dirname = path.dirname(filePath);
if (fs.existsSync(dirname)) {
return true;
}
ensureDirectoryExistence(dirname);
fs.mkdirSync(dirname);
}
ensureDirectoryExistence(target);
var cbCalled = false;
var rd = fs.createReadStream(source);
rd.on("error", function (err) {
done(err);
});
var wr = fs.createWriteStream(target);
wr.on("error", function (err) {
done(err);
});
wr.on("close", function (ex) {
done();
});
rd.pipe(wr);
function done(err) {
if (!cbCalled) {
cb(err);
cbCalled = true;
}
}
}
function copyFilePromise(source, target) {
return new Promise(function (accept, reject) {
copyFile(source, target, function (data) {
if (data === undefined) {
accept();
} else {
reject(data);
}
});
});
}
function copyMultiFilePromise(srcTgtPairArr) {
var copyFilePromiseArr = new Array();
srcTgtPairArr.forEach(function (srcTgtPair) {
copyFilePromiseArr.push(copyFilePromise(srcTgtPair[0], srcTgtPair[1]));
});
return Promise.all(copyFilePromiseArr);
}
उपरोक्त सभी समाधान जो स्रोत फ़ाइल के अस्तित्व की जांच नहीं करते हैं, खतरनाक हैं ... उदाहरण के लिए
fs.stat(source, function(err,stat) { if (err) { reject(err) }
अन्यथा मामले के स्रोत में परिदृश्य में जोखिम होता है और लक्ष्य को एक गलती से बदल दिया जाता है, आपका डेटा स्थायी रूप से बिना किसी त्रुटि के बिना खो जाएगा।