可读流
与Buffer的读/写操作类似,Stream中的可读流和可写流也用于读/写操作。
使用文件流进行文件复制,首先需要创建一个可读流,可读流可以让用户在源文件中分块读取文件中的数据,然后再从可读流中读取数据。在Node.js中,创建可读流的语法如下:
fs.createReadStream(path[, options])
在上述语法中,path代表文件路径,options是一组key-vaune 值,常用的设置如表所示。
值 | 说明 |
---|---|
flags | 对文件进行何种操作,默认为r,读文件 |
encoding | 指定编码,默认为null,如果不设置具体的编码格式,读出的数据就是Buffer类型;也可以使用rs.setEncoding()指定编码格式 |
start | 从start 开始读取文件 |
end | 读取文件到end为止(包括end) |
由于流是基于EventEmitter的,从流读取数据最好的方法是监听数据事件(dataevent), 并附加一个回调函数,当一个数据块有效时,可读流会触发一个 data事件,并执行回调函数,返回数据,这个操作是循环进制的,一直到读取完毕。在读取发生错误或者读取完毕就会触发error 或者end事件。
下面通过一个案例来演示Node.js如何从流中读取数据。
- 在chapter05中创建文件input.txt,在该文件中添加内容“老师是我心中的太阳,她教给了我们知识”。
- 在captero05目录中创建文件demo5-5.js,并在该文件中添加如下代码。
demo5-5.js:
/*
* 从流中读取数据
*/
var fs=require("fs");
var total='';
//创建可读流
var readableStream=fs.createReadStream('input.txt');
//设置编码为utf8
readableStream.setEncoding('UTF-8');
//处理流事件 data\end\and\error
readableStream.on('data',function(chunk) {
total+=chunk;
});
readableStream.on('end',function(){
console.log(total);
});
readableStream.on('error',function(err){
console.log(err.stack);
});
console.log("程序执行完毕");
在上述代码中,由于创建可读流的createReadStream()函数由fs模块提供,所以需要首先加载fs模块,创建完成后readableStream这个流是一个静止的状态, 在第11行绑定了data事件,并附加了一个回调函数的时候,流就开始流动。之后数据就会通过chunk参数流向(传递)给回调函数。chunk 参数代表触发data事件后返回的数据块,每返回一次都在第12行追加到toal中,第14-16行用于处理流事件end,在读取结束后输出数据total,第17-19行用来处理流的错误事件eror。
打开终端,执行dmoe5-5.js,.执行结果如图所示。
出现上图情况是因为当时在建input.txt的编码格式是ANSI,不是UTF-8,只要把input.txt的编码格式改成utf-8,就好了。打开input.txt,选择另存为,就会出现编码格式了,如图所示,选择utf-8。
然后打开终端,再次运行dmoe5-5.js,执行结果如下:
从上图可以看出,数据被成功读取了,并且流事件的操作都是异步的,所以首先输出“程序执行完毕” ,然后输出内容。