Can多个fs.写入追加到同一文件保证执行顺序
Can Multiple fs.write to append to the same file guarantee the order of execution?
假设我们有这样一个程序:
// imagine the string1 to string1000 are very long strings, which will take a while to be written to file system
var arr = ["string1",...,"string1000"];
for (let i = 1; i < 1000; i++) {
fs.write("./same/path/file.txt", arr[i], {flag: "a"}});
}
我的问题是,will string1 to string1000 be gurantted to append to the same file in order?
因为fs。write是异步函数,我不确定每次调用fs.write()是如何真正执行的。我假设对每个字符串的函数调用应该放在another thread
中的某个地方(如callstack
?),一旦前一个调用完成,下一个调用可以执行。
我不确定我的理解是否准确。
编辑1
在评论和回答中,我看到fs.write
在不等待callback
的情况下多次写入同一文件是不安全的。但是写流呢?
如果我使用下面的代码,它能保证写入的顺序吗?
// imagine the string1 to string1000 are very long strings, which will take a while to be written to file system
var arr = ["string1",...,"string1000"];
var fileStream = fs.createWriteFileStream("./same/path/file.txt", { "flags": "a+" });
for (let i = 1; i < 1000; i++) {
fileStream.write(arr[i]);
}
fileStream.on("error", () => {// do something});
fileStream.on("finish", () => {// do something});
fileStream.end();
任何意见或更正将是有帮助的!谢谢!
医生说
注意,在同一个文件上多次使用
fs.write
而不等待回调是不安全的。对于这个场景,f。强烈建议使用createWriteStream
使用流是有效的,因为流本质上保证写入它们的字符串的顺序与从它们读取的顺序相同。
var stream = fs.createWriteStream("./same/path/file.txt");
stream.on('error', console.error);
arr.forEach((str) => {
stream.write(str + ''n');
});
stream.end();
另一种仍然使用fs.write
的方法是使用promise来维持顺序逻辑。
function writeToFilePromise(str) {
return new Promise((resolve, reject) => {
fs.write("./same/path/file.txt", str, {flag: "a"}}, (err) => {
if (err) return reject(err);
resolve();
});
});
}
// for every string,
// write it to the file,
// then write the next one once that one is finished and so on
arr.reduce((chain, str) => {
return chain
.then(() => writeToFilePromise(str));
}, Promise.resolve());
您可以使用节点读/写锁定同步对文件的访问,请参阅以下示例,您可以阅读文档
var ReadWriteLock = require('rwlock');
var lock = new ReadWriteLock();
lock.writeLock(function (release) {
fs.appendFile(fileName, addToFile, function(err, data) {
if(err)
console.log("write error"); //logging error message
else
console.log("write ok");
release(); // unlock
});
});
我遇到了同样的问题,并为我的项目编写了一个NPM包来解决它。它的工作方式是将数据缓冲在数组中,并等待事件循环结束,在对fs.appendFile
的单个调用中连接和写入数据:
const SeqAppend = require('seqappend');
const writeLog = SeqAppend('log1.txt');
writeLog('Several...');
writeLog('...logged...');
writeLog('.......events');
你可以使用json-stream包来实现它
相关文章:
- 如何在php中按元素按字母顺序排列json文件
- 带有 CommonsChunkPlugin 的 Webpack 会导致 html 文件中的捆绑顺序错误
- 是否可以通过 AJAX *按顺序*上传文件
- 可以在Rails4中更改JavaScript文件的加载顺序吗
- 如何通过grunt contrib uglify按顺序缩小js文件
- zend按顺序加载js文件
- 使用grunt以正确的顺序插入ember文件
- Gulp-Concat文件的顺序然后是任何其他的js文件
- 分开的javascript文件和按相同顺序合并的文件在技术上有什么区别
- Javascript文件依赖项未通过清单顺序解决
- 如何在多个文件中设置摩卡测试用例的执行顺序
- Rails 指定 JavaScript 文件的加载顺序
- 按 csv 文件的顺序读取列
- blueimp jQuery 文件上传新文件顺序
- 尽管文件顺序正确,但$highcharts不是一个函数
- 播放MP3文件顺序没有HTML5音频与JavaScript
- Gulp-uglify不保存文件顺序
- 节点.js服务器读取文件顺序
- 处理与 WebPack 串联有关的文件顺序
- gulp中不可预测的文件顺序