【发布时间】:2017-03-10 14:57:57
【问题描述】:
假设我们有这样一个程序:
// 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
正如在 cmets 和答案中一样,我看到 fs.write 对于多次写入同一个文件而不等待 callback 是不安全的。但是 writestream 呢?
如果我用下面的代码,能保证写的顺序吗?
// 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();
任何 cmets 或更正都会有所帮助!谢谢!
【问题讨论】:
-
如果你的意思是
fs.writeFile(),那么文档指出“......在同一个文件上多次使用fs.writeFile而不等待回调是不安全的”. -
请注意,由于 node.js 中缓冲的工作方式,不等待回调不会影响顺序或写入。不安全的是缓冲区溢出的可能性。所以风险在于丢失写入,而不是无序写入。
-
@slebetman,感谢您的回复。但是这里的缓冲到底是什么意思呢?
-
@Lubor:核心 node.js 通过为每个打开的文件生成一个线程来管理文件/磁盘 I/O。当您写入时,您实际上并没有写入文件。相反,您要做的是向此 I/O 线程发送消息。所以这个 I/O 线程需要将此消息存储在 RAM 中的某个位置。这是 I/O 缓冲区。我相信它的大小在编译时是固定的。然后,只要文件可写,线程就会执行适当的异步 I/O 循环,将数据从该缓冲区写入磁盘(当文件的操作系统写入缓冲区为空时,您的操作系统再次不会写入磁盘,而是以类似的方式缓冲)
-
@Lubor:从我在回答类似问题时读到的代码中,我可以看到进入此 I/O 缓冲区并从该缓冲区中取出以写入磁盘的字符串的顺序得到保证。缓冲区无法重新排列,因此您写入的顺序就是将写入磁盘的顺序。但如果缓冲区已满,您的写入将被忽略。
标签: javascript node.js asynchronous fs