javascript – Node.js:如何在Write Stream’finish’事件上写()

我正在使用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);

解决方

谢谢Jordan& pNre帮助我解决这个问题.

解决方案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,next) {
     this.push(line);
     next();
  }))
  .pipe(write_stream,{ end: false });

read_stream.on('end',function() {
  write_stream.end('</svg>');
});

解决方案2(特定于through / through2转换流)

through2具有可用于写入最终数据的刷新功能.

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,next) {
    this.push(line);
    next();
  },function(flush) {
    this.push('</svg>');
    flush();
  }))
  .pipe(write_stream);

解决方法

看起来管道在完成时会关闭流.

http://nodejs.org/api/stream.html的文档说明:

By default end() is called on the destination when the source stream emits end,so that destination is no longer writable. Pass { end: false } as options to keep the destination stream open.

This keeps writer open so that “Goodbye” can be written at the end.

reader.pipe(writer,{ end: false });
reader.on('end',function() {
  writer.end('Goodbye\n');
});

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...