【问题标题】:Error writing to file fs stream NodeJS写入文件 fs 流 NodeJS 时出错
【发布时间】:2016-12-15 16:02:43
【问题描述】:

目标

使用csv-write-stream 和 fs 流将一个非常大的数组写入文件。

背景

我有一个小型应用程序,可将大量数据(数千个条目)写入 CSV 文件。为了实现这一点,我使用了前面提到的库,它只不过是 fs 流的掩码(方便)。但是,应用程序在运行时崩溃,我不知道为什么。

错误

文件被创建并且流开始写入它,但是在执行过程中我总是遇到同样的错误:

events.js:141
      throw er; // Unhandled 'error' event
      ^

Error: write after end
    at writeAfterEnd (_stream_writable.js:166:12)
    at WriteStream.Writable.write (_stream_writable.js:211:5)
    at ondata (_stream_readable.js:536:20)
    at emitOne (events.js:77:13)
    at emit (events.js:169:7)
    at Readable.read (_stream_readable.js:368:10)
    at flow (_stream_readable.js:751:26)
    at WriteStream.<anonymous> (_stream_readable.js:609:7)
    at emitNone (events.js:67:13)
    at WriteStream.emit (events.js:166:7)

代码

我知道这个错误与这段代码有关:

let writer = csvWriter({
    headers: ['country', 'postalCode']
});
let fsStream = fs.createWriteStream('output.csv');
writer.pipe(fsStream);

//very big array !
currCountryCodes = [{country: 'A', postalCode: 0}, {country: 'B', postalCode: 1 }];

for (let j = 0; j < currCountryCodes.length; j++) {
    writer.write(currCountryCodes[j]);
}

writer.end(function() {
  fsStream.end(function() {
    console.log('=== CSV written successfully, stopping application ===');
    process.exit();
  });
});

最具体的执行:

fsStream.end(function() {
        console.log('=== CSV written successfully, stopping application ===');
        process.exit();
      });

但我不明白为什么会这样。不知何故,它只发生在我正在编写的数组有数千行时,如果我只有十几行,它运行得很好。

问题

通过阅读错误,我得到的印象是在关闭流后我仍在写入文件,但这不可能发生,因为这些函数仅在所有内容都刷新到文件时运行(对吗?)

  • 我的代码有什么问题?

【问题讨论】:

    标签: node.js csv fs csv-write-stream


    【解决方案1】:

    问题是您(可以理解地)假设当writer.end() 的回调被调用时,不会再向fsStream 写入数据,但事实并非如此(如错误所示)。

    writerduplex stream,这意味着它既可读又可写。通过调用.end() 方法,您是在告诉它您不会再给它写信了。但是,这并不意味着它仍然不可读。

    当您随后结束 fsStream 时,某些缓冲区中仍有未刷新的数据将通过管道传输到 fsStream,从而产生错误。

    您可以通过侦听writer 上的end 事件来解决此问题,这是可读的等效信号,表示没有数据可供读取:

    writer.end(function() {
      writer.on('end', function() {
        fsStream.end(function() {
          console.log('=== CSV written successfully, stopping application ===');
          process.exit();
        });
      });
    });
    

    编辑:我认为当writer.end()被调用时,fsStream也会自动结束(所以fsStream.end()是多余的,它的回调可能不会被调用,因为@987654336 @ 事件已经发出)。

    如果您想确保所有数据都已刷新到输出文件,您可以在fsStream 上监听finish 事件:

    writer.end(function() {
      fsStream.on('finish', function() {
        console.log('=== CSV written successfully, stopping application ===');
        process.exit();
      });
    });
    

    甚至:

    fsStream.on('finish', function() {
      console.log('=== CSV written successfully, stopping application ===');
      process.exit();
    });
    
    writer.end();
    

    【讨论】:

    • 虽然您的建议不再出现错误,但最终消息'=== CSV written successfully, stopping application ===' 不再出现并且应用程序不再终止:S 也许现在我不需要关注 fsStream 事件?
    • @Flame_Phoenix 查看我的编辑。我认为因为.pipe(),你不需要结束fsStream
    猜你喜欢
    • 2017-12-02
    • 1970-01-01
    • 1970-01-01
    • 2021-04-04
    • 2018-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多