写入文件 fs 流 NodeJS 时出错
Posted
技术标签:
【中文标题】写入文件 fs 流 NodeJS 时出错【英文标题】:Error writing to file fs stream 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();
);
但我不明白为什么会这样。不知何故,它只发生在我正在编写的数组有数千行时,如果我只有十几行,它运行得很好。
问题
通过阅读错误,我得到的印象是在关闭流后我仍在写入文件,但这不可能发生,因为这些函数仅在所有内容都刷新到文件时运行(对吗?)
我的代码有什么问题?【问题讨论】:
【参考方案1】:问题是您(可以理解地)假设当writer.end()
的回调被调用时,不会再向fsStream
写入数据,但事实并非如此(如错误所示)。
writer
是duplex 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
。以上是关于写入文件 fs 流 NodeJS 时出错的主要内容,如果未能解决你的问题,请参考以下文章