NodeJS 流操作 stream

发布于 2024-09-17 01:42:36 字数 4232 浏览 11 评论 0

模块概览

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 包括 zlibcrypto ,这里举个简单例子:文件的 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);

相关链接

https://nodejs.org/api/stream.html

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

楠木可依

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

内心激荡

文章 0 评论 0

JSmiles

文章 0 评论 0

左秋

文章 0 评论 0

迪街小绵羊

文章 0 评论 0

瞳孔里扚悲伤

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文