每天学习一点点,成功增加一大步

NodeJS基础:Stream(流)

NodsJS zhanghui 489℃

Stream 是一个抽象接口,Node 中有很多对象实现了这个接口。例如,对http 服务器发起请求的request 对象就是一个 Stream,还有stdout(标准输出)。

Node.js,Stream 有四种流类型:

  • Readable – 可读操作。
  • Writable – 可写操作。
  • Duplex – 可读可写操作.
  • Transform – 操作被写入数据,然后读出结果。

所有的 Stream 对象都是 EventEmitter 的实例。常用的事件有:

  • data – 当有数据可读时触发。
  • end – 没有更多的数据可读时触发。
  • error – 在接收和写入过程中发生错误时触发。
  • finish – 所有数据已被写入到底层系统时触发。

下面是一个 NodeJS 简单的读写文件的操作例子

 var fs = require('fs');

// 创建可读流
var read_data = '';
var readerStream = fs.createReadStream('./input.txt');
// 设置编码为 utf8
readerStream.setEncoding('UTF8');
// 处理事件 ——> data, end and error
readerStream.on('data', function(chunk){
    read_data += chunk;
});
readerStream.on('end', function(){
    console.log(read_data);
    console.log('读取完成');
});
readerStream.on('error', function(error){
    console.log(error.stack);
});

// 创建可写流
var write_data = 'PKCMS 域名地址:pkcms.cn';
var writerStream = fs.createWriteStream('./output.txt');
// 使用 utf8 编码写入数据
writerStream.write(write_data, 'UTF8');
// 标记文件末尾
writerStream.end();
// 处理流事件 ——> finish and error
writerStream.on('finish', function(){
    console.log('写入完成。');
});
writerStream.on('error', function(err){
    console.log(err.stack);
});

console.log('程序执行完毕')

还有一种追加的写法

var path = './build/logger.txt';
var buffer = new Buffer(dateTime() + ' -> ' + msg) + "\r\n";
var exists = fs.existsSync(path);
if (exists == true) {
    var err = fs.appendFileSync(path,buffer);
    if(err) {
        console.error(err);
    } else {
        // console.log('追加内容完成');
    }
} else {
    var err = fs.writeFileSync(path, buffer);
    if(err) {
        console.error(err);
    } else {
        // console.log('写入成功');
    }
}

上面的是两个简单的【可读流】和【写入流】的例子,但试想下我们会不会遇到将从 A 文件中读取的内容直接保存到 B 文件的需求,答案肯定有,那么如何实现呢,这就要应用到了 NodeJS 的另一个流【管道流】,下面倒是一个【管道流】的例子。

var fs = require('fs');
// 管道流
var conduitStream_reader = fs.createReadStream('./input.txt');
var conduitStream_writer = fs.createWriteStream('./output2.txt');
conduitStream_reader.pipe(conduitStream_writer);
console.log('程序执行完毕');

最后了解下 nodeJS 的另一个流【链式流】,这个流的作用是通过连接输出流到另外一个流并创建多个对个流操作链的机制。链式流一般用于管道操作。下面管道和链式来压缩和解压文件。

创建 compress.js 文件,用来执行压缩操作。

 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('压缩完毕');

创建 decompress.js 文件,用来执行解压操作。

 var fs = require('fs');
var zlib = require('zlib');

fs.createReadStream('./input.txt.gz')
    .pipe(zlib.createGunzip())
    .pipe(fs.createWriteStream('./input1.txt'));

console.log('解压完成');

例子 GITHUB 地址:https://github.com/366065186/nodejs-demo/tree/master/Stream

转载请注明:隨習筆記 » NodeJS基础:Stream(流)