console.log中的节点stream缓冲区vs process.stdout.write

使用NodeJS v5.6,我创build了一个名为read-stream.js的文件:

 const fs = require('fs'), stream = fs.createReadStream(process.argv[2]); stream.on('data', function(chunk) { process.stdout.write(chunk); }); stream.on('error', function(err) { process.stderr.write("ERROR: " + err.message + "\n"); }); 

和一个名为target.txt纯文本数据文件:

 hello world this is the second line 

如果我做node read-stream.js target.txt的内容正常打印在我的控制台,一切都很好。

但是,如果我切换process.stdout.write(chunk);console.log(chunk); 那么我得到的结果是这样的:

 <Buffer 68 65 6c 6c 6f 20 77 6f 72 6c 64 0a 74 68 69 73 20 69 73 20 74 68 65 20 73 65 63 6f 6e 64 20 6c 69 6e 65 0a> 

我最近发现,通过做console.log(chunk.toString()); 我的文件的内容再次正常打印。

根据这个问题 , console.log应该使用process.stdout.write并添加一个\n字符。 但是在这里编码/解码究竟发生了什么?

提前致谢。

我相信我知道发生了什么事情:

NodeJS中console.log的实现是这样的:

 Console.prototype.log = function() { this._stdout.write(util.format.apply(this, arguments) + '\n'); }; 

然而, util.formatlib/util.jsutil.format 函数在任何input对象上都使用了inspect方法,这个方法依次返回一个对象的string表示forms,这对于debugging很有用。

因此,这里发生的是由于util.format “对象强制转换”,无论何时我们将一个对象传递给console.log ,该特定对象首先变成一个string表示, 然后 作为一个string传递给process.stdout.write最后写入terminal。

所以,当我们直接使用process.stdout.write和buffer对象时, util.format被完全忽略,每个字节都直接写入terminal,因为process.stdout.write是直接处理它们的。

process.stdout是一个stream,它的write()函数只接受string和缓冲区。 chunk是一个Buffer对象, process.stdout.write直接在控制台中写入数据的字节,使它们显示为string。 console.log在输出Buffer对象之前build立一个Buffer对象的string表示forms,因此<Buffer在开始时表示对象的types,后面是这个缓冲区的字节。

在附注中, process.stdout是一个stream,您可以直接将其传递给它,而不是读取每个块:

 stream.pipe(process.stdout);