概述
Stream 是一个抽象接口,Node 中有很多对象实现了这个接口。例如,对 http 服务器发起请求的 request 对象就是一个 Stream,还有 stdout(标准输出)也是一个 Stream。
Node.js,Stream 有四种流类型:
Readable
:可读操作。Writable
:可写操作。Duplex
:可读可写操作.Transform
:操作被写入数据,然后读出结果。
所有的 Stream 对象都是 EventEmitter 的实例。常用的事件有:
data
:当有数据可读时触发。end
:没有更多的数据可读时触发。error
:在接收和写入过程中发生错误时触发。finish
:所有数据已被写入到底层系统时触发。
从流中读取数据
读取的基本方法是:通过监听 data
事件,数据会在回调函数的参数中回传。
一个示例程序如下:
1
2
3
4
5
6
7
8
9
10
11
12
| var fs = require("fs");
var data = '';
var readerStream = fs.createReadStream('test.txt');
readerStream.setEncoding('UTF8');
// 处理流事件 --> data, end, and error
readerStream.on('data', chunk => { data += chunk; });
readerStream.on('end', () => { console.log(data); });
readerStream.on('error', err => { console.log(err.stack); });
console.log("Done!!");
|
1
2
3
| $ node readstream.js
Done!!
laji shesl's test case
|
向流中写入数据
写入的基本方法是调用 write
方法。
一个示例程序如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
| var fs = require("fs");
var data = "laji shesl's test case";
var writerStream = fs.createWriteStream('test.txt');
// 处理流事件 --> data, end, and error
writerStream.on('finish', () => { console.log("Finish."); });
writerStream.on('error', (err) => { console.log(err.stack); });
writerStream.write(data,'UTF8');
writerStream.end();
console.log("Done!!");
|
1
2
3
| $ node writestream.js
Done!!
Finish.
|
查看内容:
1
2
| $ cat test.txt
laji shesl's test case%
|
管道流
这里的管道,与 Unix 设计思想中的管道概念是相同的。它将输入流发送给输出流。
示例程序如下:
1
2
3
4
5
6
7
8
9
10
| var fs = require("fs");
var readerStream = fs.createReadStream('input.txt');
var writerStream = fs.createWriteStream('output.txt');
// 管道读写操作
// 读取 input.txt 文件内容,并将内容写入到 output.txt 文件中
readerStream.pipe(writerStream);
console.log("Done!!!");
|
链式流
简单的说链式流就是连续调用管道流,就如同 Unix 中的命令一样。它之所以可以这么做就等同于 C++ 中 <<
的返回值原理是一样的。
下面是压缩和解压缩的程序的例子:
1
2
3
4
5
6
7
8
9
| var fs = require("fs");
var zlib = require('zlib');
// 压缩 input.txt 文件为 input.txt.gz
fs.createReadStream('input.txt')
.pipe(zlib.createGzip())
.pipe(fs.createWriteStream('input.txt.gz'));
console.log("File compose done!!");
|
1
2
3
4
5
6
7
8
9
| var fs = require("fs");
var zlib = require('zlib');
// 解压 input.txt.gz 文件为 input.txt
fs.createReadStream('input.txt.gz')
.pipe(zlib.createGunzip())
.pipe(fs.createWriteStream('input.txt'));
console.log("File decompose done!!");
|