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');
});
createReadStream
và createWriteStream
lỗ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.log
thông qua require('child_process').exec
?
copy
khô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;
}
}
}
WriteStream
chú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/createWriteStream
phương thức hoạt động vì một số lý do, nhưng sử dụng fs-extra
mô-đ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 :-)
close
nên finish
dà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));
*Sync
phươ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.existsSync
gọi nên được bỏ qua. Tập tin có thể biến mất trong khoảng thời gian giữa fs.existsSync
cuộc gọi và fs.readFileSync
cuộc gọi, điều đó có nghĩa là fs.existsSync
cuộc gọi không bảo vệ chúng tôi khỏi bất cứ điều gì.
false
nếu fs.existsSync
thất bại có khả năng là công thái học kém vì ít người tiêu dùng copySync
sẽ 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_FICLONE
cờ. 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.