【问题标题】:nodejs empty file on 'finish' after pipe()管道()之后“完成”的nodejs空文件
【发布时间】:2015-12-14 13:18:54
【问题描述】:

我将可读流写入文件并想知道它何时完成,以便我可以访问磁盘上的文件。 我收听finish 事件,但是当我在侦听器中执行stat 时,文件大小为0。经过一些延迟后,大小是正确的。

这是正常行为吗?

根据docs,当所有数据都已刷新到底层系统时触发事件。

var ws = fs.createWriteStream(path);
file.pipe(ws); // file is a readable stream
ws.on('finish', function() {
    try {
        stat = fs.statSync(path); // stat.size: 0
    }
    catch (err) { /*...*/ }
});

【问题讨论】:

  • 你可以试试异步fs.stat方法吗? nodejs.org/api/fs.html#fs_fs_stat_path_callback
  • 为什么异步版本会不同? stat 只是为了显示问题,我想做gm(path),因为空文件而失败。
  • 既然你说它稍后会起作用,我想知道是否存在一个错误,即当事件循环上有其他 JS 命令时该事件被触发太快(完成写入文件)。异步版本将使任何待处理的命令完成。不是真正的答案,但可以提供有关潜在问题的更多详细信息。
  • 我尝试了异步 stat 并得到了相同的结果。
  • 在其他语言中,您可以访问sync(2)。但是尝试寻找 JavaScript、fs 和同步 - 你会生气的。节点 7+ 中似乎有 fsync,但我也无法可靠地让它工作:-(

标签: node.js stream fs


【解决方案1】:

finish 事件在所有数据都写入流但当时可能未关闭文件时触发。您可以监听文件处理程序关闭后发出的close 事件。

ws.once('close', function() {
    try {
        stat = fs.statSync(path);
    }
    catch (err) { /*...*/ }
});

【讨论】:

  • 这似乎有效,但docs 没有提到任何可写流的close 事件......同样在源代码中我看到它只发出finish。我错过了什么?
  • 是的,文档只有open 事件,但您可以查看源代码herehere
  • 我现在明白了,谢谢。我想知道为什么这是无证的。我接受您的回答,因为它解释了正在发生的事情,但是我对这个解决方案并不完全满意。有没有其他方法可以将可读流写入文件(除了处理data 事件)?
  • 我不知道除了pipe()data 事件之外的任何其他方式。
  • 就我而言,即使在等待close 时,我也无法立即读取同一个文件。
【解决方案2】:

正确的捕获事件示例

var ws = fs.createWriteStream(path);
var stream = file.pipe(ws); // file is a readable stream
stream.on('finish', function() {
    try {
        stat = fs.statSync(path); // stat.size: 0
    }
    catch (err) { /*...*/ }
});

【讨论】:

    猜你喜欢
    • 2015-11-16
    • 1970-01-01
    • 2019-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-28
    • 2017-04-07
    • 2020-01-03
    相关资源
    最近更新 更多