【问题标题】:Node.js: closing a file after writingNode.js:写入后关闭文件
【发布时间】:2020-09-06 19:34:36
【问题描述】:

我目前正在使用writer = fs.createWriteStream(url) 将可写流写入文件,使用writer.write() 进行多次写入,最后我使用writer.end()。我注意到当我执行writer.end() 时,文件大小仍然为零,并且在程序终止之前一直保持为零,此时它达到正确的大小并且内容可见且正确。

所以writer.end() 似乎没有关闭文件。

规范说“如果在'error'或'finish'时将autoClose设置为true(默认行为),文件描述符将自动关闭。”

我不确定这里的“错误”或“完成”指的是什么。大概是事件:但它们与我在writer.end() 上的电话有什么关系?我必须做些什么来引发这些事件吗?

我会尝试直接获取文件描述符并在写入后显式调用 fd.close() 以关闭它,但我没有看到在给定文件描述符的情况下获取可写流的方法。

有什么建议吗?

【问题讨论】:

标签: node.js fs


【解决方案1】:

当您调用.write 时,Node 不会立即写入文件,但它会缓冲所有块,直到达到highWaterMark 字节。此时它会尝试将内容刷新到磁盘。

为什么检查.write返回值很重要,如果返回false意味着你需要等到drain事件被触发,如果你不这样做,你可以耗尽内存应用程序,请参阅: why does attempting to write a large file cause js heap to run out of memory

.end 也是如此。它不会立即关闭文件,首先它会刷新缓冲区,在将所有内容写入文件后,它会关闭fd

因此,一旦您调用.end,您就必须等到finish 事件发出。

'finish' 事件在 stream.end() 方法执行后触发 调用,所有数据都已刷新到底层系统。

const { once } = require('events');
const fs = require('fs');

const writer = fs.createWriteStream('/tmp/some-file');
// using top-level await, wrap in IIFE if you're running an older version
for(let i = 0; i < 10; i++) {
   if(!writer.write('a'))
     await once(writer, 'drain');
}
writer.end();
await once(writer, 'finish');
consle.log('File is closed and all data has been flushed');

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-02
    • 1970-01-01
    • 2017-09-15
    • 2013-10-31
    • 2013-03-29
    相关资源
    最近更新 更多