在节点中流式传输文件会引入意外字符

时间:2015-10-03 23:48:53

标签: node.js

我需要编写一个读取字符的可读流(其中一些值的值大于128)并管道写入流。在简单的程序中,我从节点流文档中的一个例子中剔除了,我在引入字符时遇到了问题(十进制值194)。给出示例代码

var stream = require('stream');
var util = require('util');
var Readable = stream.Readable;
var Writable = stream.Writable;
util.inherits(ArrayStream, Readable);
util.inherits(OutStream, Writable);

function ArrayStream(opt, length, array) {
  Readable.call(this, opt);
  this._max = length;
  this._index = 1;
  this._array = array;
}
ArrayStream.prototype._read = function() {
  var i = this._index++;
  if (i > this._max)
    this.push(null);
  else {
    this.push(String.fromCharCode(this._array[i-1]));
  }
};

function OutStream(opt) {
  Writable.call(this, opt);
}

OutStream.prototype._write = function(chunk, encoding, next) {
  for (var i = 0; i < chunk.length ; i++) {
    console.log('     > ', chunk[i]);
  }
  next();
};

var inputArray = [5,65,66,127,128,129,170,171];
var writable = new OutStream({});
console.log('"' + String.fromCharCode(186) + '"', String.fromCharCode(170).length);
new ArrayStream({},inputArray.length, inputArray).pipe(writable);

我得到了输出

"º" 1
     >  5
     >  65
     >  66
     >  127
     >  194
     >  128
     >  194
     >  129
     >  194
     >  170
     >  194
     >  171

我很想知道194s出现的原因,以及我可以做些什么来避免它。

1 个答案:

答案 0 :(得分:0)

由于您不在objectMode,因此节点会使用默认的utf-8编码将字符串转换为缓冲区。由于utf-8是多字节编码,因此它将表示具有多个字节的非ASCII字符。因此,对于某些字符,您将获得chunk个更多的字节。这是一个简单的例子:

Buffer(String.fromCharCode(170)).length // 2
Buffer(String.fromCharCode(170)).toJSON() // [ 194, 170 ]

Buffer(String.fromCharCode(65)).length // 1 for ASCII
Buffer(String.fromCharCode(65)).toJSON() //  [ 65 ]

您真的不需要为可写流中的块运行循环。整个块表示一个字符:

OutStream.prototype._write = function(chunk, encoding, next) {      
    console.log('     > ', chunk.toString().charCodeAt(0))
    next();
};