前面我们已经学习了如何使用fs模块中的readFile方法、readFileSync方法读取文件中内容,及如何使用fs模块中的writeFile方法、writeFileSync方法向一个文件写入内容。
用readFile方法或readFileSync方法读取文件内容时,Node.js首将文件内容完整地读入缓存区,再从该缓存区中读取文件内容。在使用writeFile方法或writeFileSync方法写入文件内容时,Node.js首先将该文件内容完整地读人缓存区,然后一欠性将缓存区中内容写入到文件中。
无论是read和write都是把文件视为一个整体,也是说,NodeJs需要在内存中开辟与文件相等大小的空间,如果文件小,这的确没有问题,但是如果是一个非常大的(10G)文件会怎样?内存根本装不下。
1.Stream流介绍
应用程序中,流是一组有序的、有起点和终点的字节数据的传输方式。在应用程序中各种对象之间交换与传输数据的时候,总是先将该对象中所包含的数据转换为各种形式的流数据(即字节数据),再通过流的传输,到达目的对象后再将流数据转换为该对象中可以使用的数据。
流分为输入流与输出流
2. Stream流读取
fs = require('fs'); var dataContent = ''; //存储每次读取的数据 // 设置编码为 utf8。 //创建输入流 var readerStream = fs.createReadStream("./a.txt",new Buffer(20)); readerStream.setEncoding('UTF8'); //注册读取数据的事件 readerStream.on("data",function(content){ dataContent+=content; console.log(dataContent); }); readerStream.on("err",function(err){ console.error("出现err",err); }) //读取数据完毕的事件 readerStream.on("end",function(){ console.log("读取完毕"); console.log(dataContent); })
3.stream写入流
var fs = require("fs");
var data = '源代码教育';
// 创建一个可以写入的流,写入到文件 my.txt 中
var writerStream = fs.createWriteStream('my.txt');
// 使用 utf8 编码写入数据
writerStream.write(data,'UTF8');
// 标记文件末尾
writerStream.end();
// 处理流事件 --> data, end, and error
writerStream.on('finish', function() {
console.log("写入完成。");
});
writerStream.on('error', function(err){
console.log(err.stack);
});
console.log("程序执行完毕");
常用方法备注:
/* * 流,在应用程序中表示一组有序的、有起点有终点的字节数据的传输手段; * Node.js中实现了stream.Readable/stream.Writeable接口的对象进行流数据读写;以上接口都继承自EventEmitter类,因此在读/写流不同状态时,触发不同事件; * 关于流读取:Node.js不断将文件一小块内容读入缓冲区,再从缓冲区中读取内容; * 关于流写入:Node.js不断将流数据写入内在缓冲区,待缓冲区满后再将缓冲区写入到文件中;重复上面操作直到要写入内容写写完; * readFile、read、writeFile、write都是将整个文件放入内存而再操作,而则是文件一部分数据一部分数据操作; * * -----------------------流读取------------------------------------- * 读取数据对象: * fs.ReadStream 读取文件 * http.IncomingMessage 客户端请求或服务器端响应 * net.Socket Socket端口对象 * child.stdout 子进程标准输出 * child.stdin 子进程标准入 * process.stdin 用于创建进程标准输入流 * Gzip、Deflate、DeflateRaw 数据压缩 * * 触发事件: * readable 数据可读时 * data 数据读取后 * end 数据读取完成时 * error 数据读取错误时 * close 关闭流对象时 * * 读取数据的对象操作方法: * read 读取数据方法 * setEncoding 设置读取数据的编 * pause 通知对象众目停止触发data事件 * resume 通知对象恢复触发data事件 * pipe 设置数据通道,将读入流数据接入写入流; * unpipe 取消通道 * unshift 当流数据绑定一个解析器时,此方法取消解析器 * * ------------------------流写入------------------------------------- * 写数据对象: * fs.WriteStream 写入文件对象 * http.clientRequest 写入HTTP客户端请求数据 * http.ServerResponse 写入HTTP服务器端响应数据 * net.Socket 读写TCP流或UNIX流,需要connection事件传递给用户 * child.stdout 子进程标准输出 * child.stdin 子进程标准入 * Gzip、Deflate、DeflateRaw 数据压缩 * * 写入数据触发事件: * drain 当write方法返回false时,表示缓存区中已经输出到目标对象中,可以继续写入数据到缓存区 * finish 当end方法调用,全部数据写入完成 * pipe 当用于读取数据的对象的pipe方法被调用时 * unpipe 当unpipe方法被调用 * error 当发生错误 * * 写入数据方法: * write 用于写入数据 * end 结束写入,之后再写入会报错;