【发布时间】:2023-04-05 22:22:01
【问题描述】:
我正在使用 Node.js 流逐行浏览文本文件,进行一些转换并输出到 SVG 文件。
我正在尝试在处理完成后写入最后一条数据(</svg>),但是当写入流发出finish 事件时,尝试write() 将抛出Error: write after end。
有什么优雅的方法可以解决这个问题吗?
注意:输入文件很大(大约 1GB),因此由于其 I/O 和内存管理,无法绕过 pipe() 方法。
var fs = require('fs');
var split2 = require('split2');
var through2 = require('through2');
var read_stream = fs.createReadStream('input.txt');
var write_stream = fs.createWriteStream('output.svg');
write_stream.write('<svg>');
write_stream.on('finish', function() {
this.write('</svg>'); // doesn't work
});
read_stream
.pipe(split2())
.pipe(through2.obj(function(line, encoding, next) {
this.push(line);
next();
}))
.pipe(write_stream);
解决方案
解决方案 1(通用)
pipe() 使用end:false 选项写入流并手动end() 流。
var fs = require('fs');
var split2 = require('split2');
var through2 = require('through2');
var read_stream = fs.createReadStream('input.txt');
var write_stream = fs.createWriteStream('output.svg');
write_stream.write('<svg>');
read_stream
.pipe(split2())
.pipe(through2.obj(function(line, encoding, next) {
this.push(line);
next();
}))
.pipe(write_stream, { end: false });
read_stream.on('end', function() {
write_stream.end('</svg>');
});
解决方案 2(特定于 through/through2 转换流)
through2有一个flush函数,可以用来写入最终数据。
var fs = require('fs');
var split2 = require('split2');
var through2 = require('through2');
var read_stream = fs.createReadStream('input.txt');
var write_stream = fs.createWriteStream('output.svg');
write_stream.write('<svg>');
read_stream
.pipe(split2())
.pipe(through2.obj(function(line, encoding, next) {
this.push(line);
next();
}, function(flush) {
this.push('</svg>');
flush();
}))
.pipe(write_stream);
【问题讨论】:
-
您好!我建议将您的解决方案从问题提取到答案部分。
-
@SlavaFominII 你能给我一些指导吗?
-
@DanBurzo 我相信 SlavaFominII 建议您编辑您的问题并删除您附加的解决方案。然后,您可以创建自己的问题答案,或通过 cmets 建议对 Jordan 和/或 pNre 的答案进行编辑。
标签: javascript node.js stream