var fs = require('fs');
var readableStream = fs.createReadStream('file.txt');
var data = '';
var chunk;
readableStream.on('readable', function(){
while ((chunk = readableStream.read()) != null) {
data += chunk;
}
});
readableStream.on('end', function(){
console.log(data);
});
read() 方法会从内部 buffer 中读取数据,当没有数据可读的时候,它会返回 null 。
因此,在 while 循环中我们检查 read() 是不是返回 null ,当它返回 null 的时候,就终止循环。
需要注意的是,当我们可以从流中读取数据的时候, readable 事件就会触发。
设置编码
默认情况下,你从流中读取到的是 Buffer 对象。如果你要读取的是字符串的话,这并不适合你。因此,你可以像下面的例子那样通过调用 Readable.setEncoding() 来设置流的编码:
var fs = require('fs');
var readableStream = fs.createReadStream('file.txt');
var data = '';readableStream.setEncoding('utf8');
readableStream.on('data', function(chunk){
data += chunk;
});
readableStream.on('end', function(){
console.log(data);
});
上面的例子中,我们把流的编码设置成 utf8 ,数据就会被解析成 utf8 ,回调函数中的 chunk 就会是字符串了。
管道 (Piping)
管道是一个很棒的机制,你不需要自己管理流的状态就可以从数据源中读取数据,然后写入到目的地中。我们先看看下面的例子:
var fs = require('fs');
var readableStream = fs.createReadStream('file1.txt');
var writableStream = fs.createWriteStream('file2.txt');readableStream.pipe(writableStream);
上面的例子利用 pipe() 方法把 file1 的内容写到 file2 中。因为 pipe() 会帮你管理数据流,你不需要担心数据流的速度。这让 pipe() 变得非常简洁易用。
需要注意的是, pipe() 会返回目的地的流,因此你可以很轻易让多个流链接起来!
链接 (Chaining)
假设有一个归档文件,你想要解压它。有很多方式可以完成这个任务。但最简洁的方式是利用管道和链接:
var fs = require('fs');
var zlib = require('zlib');fs.createReadStream('input.txt.gz')
.pipe(zlib.createGunzip())
.pipe(fs.createWriteStream('output.txt'));
首先,我们通过 input.txt.gz 创建了一个可读流,然后让它流 zlib.createGunzip() 流,它会解压内容。最后,我们添加一个可写流把解压后的内容写到另一个文件中。
其他方法
我们已经讨论了一些可读流中重要的概念了,这里还有一些你需要知道的方法:









