Dự án mà tôi đang làm việc (node.js) ngụ ý rất nhiều hoạt động với hệ thống tệp (sao chép / đọc / ghi, v.v.). Tôi muốn biết phương pháp nào là nhanh nhất và tôi rất vui khi nhận được lời khuyên. Cảm ơn.
Dự án mà tôi đang làm việc (node.js) ngụ ý rất nhiều hoạt động với hệ thống tệp (sao chép / đọc / ghi, v.v.). Tôi muốn biết phương pháp nào là nhanh nhất và tôi rất vui khi nhận được lời khuyên. Cảm ơn.
Câu trả lời:
Đây là một cách tốt để sao chép một tệp trong một dòng mã bằng các luồng:
var fs = require('fs');
fs.createReadStream('test.log').pipe(fs.createWriteStream('newLog.log'));
Trong nút v8.5.0, copyFile đã được thêm vào
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');
});
createReadStreamvà createWriteStreamlỗi, vì vậy bạn sẽ không nhận được một lớp lót (mặc dù nó sẽ vẫn nhanh như vậy).
cp test.log newLog.logthông qua require('child_process').exec?
copykhông khả dụng trên Window, trái với giải pháp Node.js đầy đủ.
child_process.execFile('/bin/cp', ['--no-target-directory', source, target]).
fs.createReadStream('./init/xxx.json').pipe(fs.createWriteStream('xxx.json'));
Cùng một cơ chế, nhưng điều này thêm xử lý lỗi:
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;
}
}
}
WriteStreamchúc chỉ unpipe nó. Bạn sẽ phải gọi rd.destroy()cho mình. Ít nhất đó là những gì đã xảy ra với tôi. Đáng buồn là không có nhiều tài liệu ngoại trừ từ mã nguồn.
cbđứng cho? những gì chúng ta nên vượt qua như là đối số thứ ba?
Tôi không thể khiến createReadStream/createWriteStreamphương thức hoạt động vì một số lý do, nhưng sử dụng fs-extramô-đun npm thì nó hoạt động ngay lập tức. Tôi không chắc chắn về sự khác biệt hiệu suất mặc dù.
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);, và chúng sẽ giải quyết mối quan tâm của @ mvillar.
Kể từ Node.js 8.5.0, chúng tôi có fs.copyFile và fs.copyFileSync mới phương pháp.
Ví dụ sử dụng:
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()bị lỗi trong khi ghi đè các tệp dài hơn. Phép lịch sự uv_fs_copyfile()cho đến Node v8.7.0 (libuv 1.15.0). xem github.com/libuv/libuv/pull/1552
Nhanh chóng để viết và thuận tiện để sử dụng, với lời hứa và quản lý lỗi.
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;
});
}
Tương tự với cú pháp async / await:
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);});và tra cứu thông số kỹ thuật về điều này và bạn đã đúng: Cố gắng giải quyết hoặc từ chối lời hứa đã giải quyết không có kết quả. Có lẽ bạn có thể mở rộng câu trả lời của mình và giải thích lý do tại sao bạn đã viết hàm theo cách này? Cảm ơn :-)
closenên finishdành cho các luồng Writable.
/dev/stdin, thì đó là lỗi github.com/joyent/node/issues/25375
Chà, thường thì tốt để tránh các hoạt động tập tin không đồng bộ. Dưới đây là ví dụ đồng bộ hóa ngắn (nghĩa là không xử lý lỗi):
var fs = require('fs');
fs.writeFileSync(targetFile, fs.readFileSync(sourceFile));
*Syncphương thức hoàn toàn chống lại triết lý của nodejs! Tôi cũng nghĩ rằng họ đang dần bị phản đối. Toàn bộ ý tưởng của nodejs là nó đơn luồng và theo sự kiện.
Giải pháp của Mike Schilling với việc xử lý lỗi với một phím tắt cho trình xử lý sự kiện lỗi.
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;
}
}
}
Nếu bạn không quan tâm đến việc nó không đồng bộ và không sao chép các tệp có kích thước gigabyte và không muốn thêm một phụ thuộc khác chỉ cho một chức năng duy nhất:
function copySync(src, dest) {
var data = fs.readFileSync(src);
fs.writeFileSync(dest, data);
}
fs.existsSyncgọi nên được bỏ qua. Tập tin có thể biến mất trong khoảng thời gian giữa fs.existsSynccuộc gọi và fs.readFileSynccuộc gọi, điều đó có nghĩa là fs.existsSynccuộc gọi không bảo vệ chúng tôi khỏi bất cứ điều gì.
falsenếu fs.existsSyncthất bại có khả năng là công thái học kém vì ít người tiêu dùng copySyncsẽ nghĩ sẽ tự kiểm tra giá trị trả lại mỗi khi nó được gọi, nhiều hơn chúng ta làm cho fs.writeFileSync et al. . Ném một ngoại lệ là thực sự thích hợp hơn.
const fs = require("fs");
fs.copyFileSync("filepath1", "filepath2"); //fs.copyFileSync("file1.txt", "file2.txt");
Đây là những gì cá nhân tôi sử dụng để sao chép một tệp và thay thế một tệp khác bằng node.js :)
Đối với các bản sao nhanh, bạn nên sử dụng fs.constants.COPYFILE_FICLONEcờ. Nó cho phép (đối với các hệ thống tệp hỗ trợ này) không thực sự sao chép nội dung của tệp. Chỉ một mục nhập tệp mới được tạo, nhưng nó trỏ đến Sao chép trên ghi " của tệp nguồn.
Không làm gì / ít hơn là cách nhanh nhất để làm một cái gì đó;)
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");
}
);
Sử dụng lời hứa thay thế:
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
Giải pháp của benweet kiểm tra mức độ hiển thị của tệp trước khi sao chép:
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);
}
});
});
}
Tại sao không sử dụng nodejs được xây dựng trong chức năng sao chép?
Nó cung cấp cả phiên bản không đồng bộ và đồng bộ hóa:
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
Giải pháp của Mike , nhưng với những lời hứa:
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);
});
};
Cải thiện một câu trả lời khác.
Đặc trưng:
promise, làm cho nó dễ sử dụng hơn trong một dự án lớn hơn.Sử dụng:
var onePromise = copyFilePromise("src.txt", "dst.txt");
var anotherPromise = copyMultiFilePromise(new Array(new Array("src1.txt", "dst1.txt"), new Array("src2.txt", "dst2.txt")));
Mã số:
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);
}
tất cả các giải pháp trên không kiểm tra sự tồn tại của tệp nguồn đều nguy hiểm ... ví dụ:
fs.stat(source, function(err,stat) { if (err) { reject(err) }
nếu không, có một rủi ro trong một kịch bản trong trường hợp nguồn và đích bị lỗi thay thế, dữ liệu của bạn sẽ bị mất vĩnh viễn mà không nhận thấy bất kỳ lỗi nào.