আমি যে প্রকল্পে কাজ করছি (নোড.জেএস) ফাইল সিস্টেমের সাথে প্রচুর ক্রিয়াকলাপ বোঝায় (অনুলিপি / পঠন / লিখন ইত্যাদি)। আমি কোন পদ্ধতিগুলি দ্রুততম তা জানতে চাই এবং আমি একটি পরামর্শ পেয়ে খুশি হব। ধন্যবাদ।
আমি যে প্রকল্পে কাজ করছি (নোড.জেএস) ফাইল সিস্টেমের সাথে প্রচুর ক্রিয়াকলাপ বোঝায় (অনুলিপি / পঠন / লিখন ইত্যাদি)। আমি কোন পদ্ধতিগুলি দ্রুততম তা জানতে চাই এবং আমি একটি পরামর্শ পেয়ে খুশি হব। ধন্যবাদ।
উত্তর:
স্ট্রিম ব্যবহার করে কোডের এক লাইনে একটি ফাইল অনুলিপি করার এটি একটি ভাল উপায়:
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উইন্ডোতে পুরো নোড.জেএস সমাধানের বিপরীতে ওয়েল পোর্টেবল নয়।
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এনপিএম মডিউলটি এটি এখনই ব্যবহার করে worked যদিও পারফরম্যান্সের পার্থক্য সম্পর্কে আমি নিশ্চিত নই।
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);অ্যাসিনক্রোনাস পদ্ধতি রয়েছে , এবং এগুলি @ এমওয়িলারের উদ্বেগ সমাধান করবে।
নোড.জেস 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()নোড ভি 8.7.0 অবধি সৌজন্যে (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");
আমি ব্যক্তিগতভাবে কোনও ফাইল অনুলিপি করতে এবং node.js ব্যবহার করে অন্য একটি ফাইল প্রতিস্থাপন করতে এটি ব্যবহার করি :)
দ্রুত অনুলিপিগুলির জন্য আপনার 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);
}
});
});
}
কেন অনুলিপি ফাংশনে নির্মিত নোডেজ ব্যবহার করবেন না?
এটি উভয়ই অ্যাসিঙ্ক এবং সিঙ্ক সংস্করণ সরবরাহ করে:
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) }
অন্যথায় উত্স এবং টার্গেট কোনও ভুল প্রতিস্থাপনের ক্ষেত্রে একটি দৃশ্যে ঝুঁকি রয়েছে, কোনও ত্রুটি না দেখে আপনার ডেটা স্থায়ীভাবে হারিয়ে যাবে।