gpt4 book ai didi

node.js - NodeJS 写入文件 fs 流时出错

转载 作者:太空宇宙 更新时间:2023-11-04 00:36:14 25 4
gpt4 key购买 nike

目标

使用 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();
});

但我不明白为什么会发生这种情况。不知何故,只有当我编写的数组有数千行时才会发生这种情况,如果我只有十几行,它就可以完美运行。

问题

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

  • 我的代码有什么问题?

最佳答案

问题是您(可以理解)假设当调用 writer.end() 的回调时,不会再将任何数据写入 fsStream ,即情况并非如此(如错误所示)。

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

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

您可以通过监听 end 来解决这个问题writer 上的事件,这相当于发出没有数据可供读取的可读信号:

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

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

如果您想确保所有数据都已刷新到输出文件,您可以监听 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();

关于node.js - NodeJS 写入文件 fs 流时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38853599/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com