NodeJS 流操作 stream
模块概览
nodejs 的核心模块,基本上都是 stream 的的实例,比如 process.stdout、http.clientRequest。
对于大部分的 nodejs 开发者来说,平常并不会直接用到 stream 模块,只需要了解 stream 的运行机制即可(非常重要)。
而对于想要实现自定义 stream 实例的开发者来说,就得好好研究 stream 的扩展 API 了,比如 gulp 的内部实现就大量用到了自定义的 stream 类型。
来个简单的例子镇楼,几行代码就实现了读取文件内容,并打印到控制台:
const fs = require('fs');
fs.createReadStream('./sample.txt').pipe(process.stdout);
Stream 分类
在 nodejs 中,有四种 stream 类型:
- Readable:用来读取数据,比如
fs.createReadStream()
。 - Writable:用来写数据,比如
fs.createWriteStream()
。 - Duplex:可读+可写,比如
net.Socket()
。 - Transform:在读写的过程中,可以对数据进行修改,比如
zlib.createDeflate()
(数据压缩/解压)。
Readable Stream
以下都是 nodejs 中常见的 Readable Stream,当然还有其他的,可自行查看文档。
- http.IncomingRequest
- fs.createReadStream()
- process.stdin
- 其他
例子一:
var fs = require('fs');
fs.readFile('./sample.txt', 'utf8', function(err, content){
// 文件读取完成,文件内容是 [你好,我是程序猿小卡]
console.log('文件读取完成,文件内容是 [%s]', content);
});
例子二:
var fs = require('fs');
var readStream = fs.createReadStream('./sample.txt');
var content = '';
readStream.setEncoding('utf8');
readStream.on('data', function(chunk){
content += chunk;
});
readStream.on('end', function(chunk){
// 文件读取完成,文件内容是 [你好,我是程序猿小卡]
console.log('文件读取完成,文件内容是 [%s]', content);
});
例子三:
这里使用了 .pipe(dest)
,好处在于,如果源文件较大,对于降低内存占用有好处。
var fs = require('fs');
fs.createReadStream('./sample.txt').pipe(process.stdout);
注意:这里只是原封不动的将内容输出到控制台,所以实际上跟前两个例子有细微差异。可以稍做修改,达到上面同样的效果
var fs = require('fs');
var onEnd = function(){
process.stdout.write(']');
};
var fileStream = fs.createReadStream('./sample.txt');
fileStream.on('end', onEnd)
fileStream.pipe(process.stdout);
process.stdout.write('文件读取完成,文件内容是[');
// 文件读取完成,文件内容是[你好,我是程序猿小卡]
Writable Stream
同样以写文件为例子,比如想将 hello world
写到 sample.txt
里。
例子一:
var fs = require('fs');
var content = 'hello world';
var filepath = './sample.txt';
fs.writeFile(filepath, content);
例子二:
var fs = require('fs');
var content = 'hello world';
var filepath = './sample.txt';
var writeStram = fs.createWriteStream(filepath);
writeStram.write(content);
writeStram.end();
Duplex Stream
最常见的 Duplex stream 应该就是 net.Socket
实例了,在前面的文章里有接触过,这里就直接上代码了,这里包含服务端代码、客户端代码。
服务端代码:
var net = require('net');
var opt = {
host: '127.0.0.1',
port: '3000'
};
var server = net.createServer((socket) => {
socket.on('data', (data) => {
console.log('client send message: ', data.toString());
});
socket.write('hello client');
});
server.listen(opt.port, opt.host, ()=>{
console.log(server.address());
});
客户端代码:
var net = require('net');
var opt = {
host: '127.0.0.1',
port: '3000'
};
var client = net.connect(opt, function(){
client.write('msg from client'); // 可写
});
// 可读
client.on('data', function(data){
// lient: got reply from server [reply from server]
console.log('client: got reply from server [%s]', data);
client.end();
});
Transform Stream
Transform stream 是 Duplex stream 的特例,也就是说,Transform stream 也同时可读可写。跟 Duplex stream 的区别点在于,Transform stream 的输出与输入是存在相关性的。
常见的 Transform stream 包括 zlib
、 crypto
,这里举个简单例子:文件的 gzip 压缩。
var fs = require('fs');
var zlib = require('zlib');
var gzip = zlib.createGzip();
var inFile = fs.createReadStream('./extra/fileForCompress.txt');
var out = fs.createWriteStream('./extra/fileForCompress.txt.gz');
inFile.pipe(gzip).pipe(out);
相关链接
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: NodeJS 域名解析 dns
下一篇: 彻底找到 Tomcat 启动速度慢的元凶
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论