@Wangww0925
2019-08-07T08:02:54.000000Z
字数 3355
阅读 207
NodeJs
流操作(stream) 一般代表文件读写操作
把一个文件比喻成一个水桶,文件里面的内容比作为水,我们用一根管子(pipe)连接两个桶使得水从一个桶流入另一个桶,这样就慢慢的实现了大文件的复制过程(也就是流的过程)。
如果读取或者写入一个比较大的文件如(音频或者视频一般为几个G左右),如果使用writeFile或者readFile来操作,非常容易使电脑内存"爆仓",因为电脑内存一般也就4G,8G左右
理想的方法应该是分多次对数据进行读写操作,不管文件有多大,只要时间允许,总会处理完成。这时后就需要有流操作了
Readable 可读操作
Writable 可写操作
Duplex 可读可写操作
Transform 操作被写入数据,然后读出结果
所有可以读取数据的流都继承自stream.Readable
所有可以写入的流都继承自stream.Writable
从文件读取数据时,可以打开一个文件流,然后从文件流中不断地读取数据
pause() - 可读流读取暂停
resume() - 可读流读取继续
data - 监听可读流读取数据事件
chunk - 数据存储在chunk中
error - 监听可读流读取失败事件
end - 监听可读流读取结束事件
var fs = require("fs");
var readStream = fs.createReadStream("./guilai.mp4"); //创建一个可读流
readStream.on("data",function(chunk){
console.log(chunk);
})
readStream.on("error",function(err){
console.log(err);
})
readStream.on("end",function(){
console.log("读取完毕")
})
向文件写入数据时,只需要把数据不断地往文件流中写进去就可以了
PS: 文件不存在则会先创建文件
write() - 向文件中写入内容 【要写入多个内容,只需要不断调用这个函数就可以了】
- write() 返回布尔值,true - 写入流完成,false - 未完成
end() - 标记文件末尾
error - 监听可写流写入失败事件
finish - 监听可写流写入结束事件
drain - 监听可写流完成后触发事件
var fs = require("fs");
var writeStream = fs.createWriteStream("03.txt"); // 创建一个可写流
writeStream.write("哈哈哈哈");
writeStream.write("html css javascript");
writeStream.end(); // 标记文件末尾
writeStream.on('error', function(err){
console.log(err.stack);
});
writeStream.on('finish', function() {
console.log("写入完成");
});
以下所用到的 guilai.mp4 ,由于视频太大无法上传,不过可以用其他音视频代替 guilai.mp4 进行测试
如果写入的速度跟不上读取的速度,有可能导致数据丢失
写入到完成耗时长
应该写完一段,再读取下一段,如果没有写完的话,就让读取流先暂停,等写完再继续,具体看 【可读流过程的 暂停 readStream.pause() 和 重启 readStream.resume()】
test.txt
hello
node 执行文件
var fs = require("fs");
var readStream = fs.createReadStream("./guilai.mp4"); // 创建可读流
var writeStream = fs.createWriteStream("./www.mp4"); // 创建可写流
readStream.on("data",function(chunk){
writeStream.write(chunk); // 将数据写入www.txt文件中
})
readStream.on("end",function(){
writeStream.end();
})
writeStream.write(chunk) 返回布尔值,true - 写入流完成,false - 未完成
var fs = require("fs");
var readStream = fs.createReadStream("./guilai.mp4"); // 创建可读流
var writeStream = fs.createWriteStream("./www.mp4"); // 创建可写流
readStream.on("data",function(chunk){
if(writeStream.write(chunk) === false){
console.log("暂停");
readStream.pause();
}
})
// drain - 监听可写流完成后触发事件
writeStream.on("drain", function(){
console.log("继续");
readStream.resume();
})
readStream.on("end", function(){
writeStream.end();
})
pipe中间管道:将可读流和可写流串联起来,一个Readable流和一个Writable流串起来后,所有的数据自动从Readable流进入Writable流,这种操作叫pipe,这样源文件的所有数据就自动写入到目标文件里了
pipe会自动调用data,end等事件
var fs = require("fs");
var readStream = fs.createReadStream("./guilai.mp4"); // 创建可读流
var writeStream = fs.createWriteStream("./www.mp4"); // 创建可写流
readStream.pipe(writeStream); // 通过pipe中间管道写入流
var fs = require("fs");
var zlib = require("zlib"); // 引入可压缩模块
var readStream = fs.createReadStream("./guilai.mp4"); // 创建可读流
var writeStream = fs.createWriteStream("./www.mp4.zip"); // 创建可写流
var gzip = zlib.createGzip(); //创建压缩流
readStream.pipe(gzip).pipe(writeStream); // 通过中间管道进行压缩然后写入到可写流中
作者 wendy
2019 年 1月 21日