在学习fs
中我们就可以操作我们的读写相关的一些文件
我们读写相关文件的时候,我们可以通过readFile
(读)和writeFile
(写)里面的某些数据
但是有一天我们读的数据很大的时候,万一我的内存并不能够直接把整个数据全部读取下来
所以我们要读取比较大的数据的时候,我们不可能一次性的把所有的数据都读取出来,这样效率太低了
我们希望的是读一点是一点
,所以我们在读写比较大的数据的时候,我们可能需要用到流
的这样子的一个接口
Node.js Stream(流)
Stream是一个抽象接口,Node中有很多对象实现了这个接口。例如:对http服务器发起请求的request,对象就是一个Stream,还有stdout(标准输出)
node.js Stream有四种流类型:
- Readable:可读操作
- Writeable:可写操作
- Dupiex:可读可写操作
- Transform:操作被写入数据,然后读出结果
所有的Stream对象都是EventEmitter的实例。常用的事件有: - data:当有数据可读时触发
- end:没有更多的数据可读时触发
- error:在接收和写入过程中发生错误时触发
- finish:所有数据已被写入过程到底层系统时触发
写入流
创建main.js
let fs = require('fs')
//写入流
let data = 'www.sxt.com'
//1.创建写入流
// --语法:fs.createWriteStream(文件路径,[可选配置操作])
//创建一个可以写入状态的流,写入到文件output.txt中
let wirterStream = fs.createWriteStream('output.txt')
//使用utf-8编码写入数据
wirterStream.write(data,'utf-8')
//标记文件末尾
wirterStream.end();
//处理流事件 --> data,end,and error
wirterStream.on('finish',function(){
console.log('写入完成')
})
wirterStream.on('error',function(err){
console.log(err.stack)
})
console.log('程序执行完毕')
执行:
node main.js
fs.createWriteStream
简写形式:
let fs = require('fs')
let ws = fs.createWriteStream('hello.txt',{flags:'w',encoding:'utf-8'})
console.log(ws)
结果:
WriteStream {
fd: null,
path: 'hello.txt',
flags: 'w',
mode: 438,
....
}
可以进行事件的监听:
//监听文件打开事件
wx.on('open',function(){
console.log('文件打开')
})
//监听准备事件
wx.on('ready',function(){
console.log('文件写入已准备状态')
})
//写入数据
wx.write("hello world",function(err){
if(err){
console.log(err)
}else{
console.log("内容流入完成")
}
})
//end:表示写入完成
wx.end(function(){
console.log('文件写入关闭')
})
//监听文件关闭事件
wx.on('close',function(){
console.log('文件写入完成关闭')
})
从流中读取数据
读和写很类似
创建input.txt
文件:
www.sxt.com
创建main.js
文件:
var fs = require('fs')
创建一个可读的流:fs.createReadStream
let readerStream = fs.createReadStream('input.txt')
设置编码为utf-8
:
readerStream.setEncoding('utf-8')
输出readStream
//1.首先导入fs模块
let fs = require('fs')
//2.创建读取流,语法:fs.createReadStream(路径,[可选配置项])
let rs = fs.createReadStream('input.txt',{flags:'r',encoding:'utf-8'})
console.log(rs)
结果:
ReadStream {
fd: null,
path: 'input.txt',
flags: 'r',
mode: 438,
start: undefined,
end: Infinity,
pos: undefined,
bytesRead: 0,
....
}
基础的打开关闭
rs.on('open',function(){
console.log('读取的文件已打开')
})
rs.on('close',function(){
console.log('读取流结束')
})
在这里我们还有专门的一个事件去处理读取:我发一段一段发给你
一点一点小心翼翼的去读取;也是采用了事件
去一点一点的去提取
我们的一点一点去提取的监听事件叫data
data
可以用来监听我们数据流的:
//每一批数据流入的完成
rs.on('data',function(chunk){
console.log('单批数据流入')
console.log(chunk)
})
小文件看不出大小,但是大文件就可以看出效果
let rs = fs.createReadStream('文件路径',{flags:'r'})
// console.log(rs)
rs.on('open',function(){
console.log('读取的文件已打开')
})
//每一批数据流入的完成
rs.on('data',function(chunk){
console.log('单批数据流入:',chunk.length)
console.log(chunk)
})
rs.on('close',function(){
console.log('读取流结束')
})
输入流配合写入流:
//1.首先导入fs模块
let fs = require('fs')
//2.创建读取流,语法:fs.createReadStream(路径,[可选配置项])
let rs = fs.createReadStream('input.txt',{flags:'r',encoding:'utf-8'})
let ws = fs.createWriteStream('a.txt',{flags:'w',encoding:'utf-8'})//写入;[可选配置项]跟读取一致
// console.log(rs)
rs.on('open',function(){
console.log('读取的文件已打开')
})
//每一批数据流入的完成
rs.on('data',function(chunk){
console.log('单批数据流入:',chunk.length)
console.log(chunk)
ws.write(chunk,()=>{console.log('单批输入流入完成')})//写入
})
rs.on('close',function(){
ws.end
console.log('读取流结束')
})
这个我们可以封装起来
let fs = require('fs')
function myFsWriteStreamTXT(FileName,neiru){
let ws = fs.createWriteStream(FileName,{flags:'w',encoding: 'utf-8'})
ws.on('open',function(){
console.log('写入开始')
})
ws.write(neiru,()=>{console.log('单批输入流入完成')})
ws.on('close',function(){
ws.end()
})
}
function myFsReadStreamTXT(FileName){
let rs = fs.createReadStream(FileName,{flags:'r',encoding:'utf-8'})
rs.on('open',function(){
console.log('读取的文件已打开')
})
rs.on('data',function(data){
console.log('单批数据流入:',data.length)
console.log(data)
})
rs.on('close',function(){
console.log('读取流结束')
})
}
function myFsReadEndWriteStreamTXT(FileName){
let rs = fs.createReadStream(FileName,{flags:'r',encoding:'utf-8'})
rs.on('open',function(){
console.log('读取的文件已打开')
})
rs.on('data',function(data){
console.log('单批数据流入:',data.length)
console.log(data)
myFsWriteStreamTXT(FileName,data)
})
rs.on('close',function(){
console.log('读取流结束')
})
}
module.exports = {myFsWriteStreamTXT,myFsReadStreamTXT,myFsReadEndWriteStreamTXT}
这样还是挺累的,所以它还有一个接口
这个接口可以让你们不用写这么多代码:用管道
管道流(学会输入输出流的原理后,这个就是关键(封装了以上的输入输出流提供给我们))
管道提供了一个输出流到输入流的机制。通过我们用于从一个流中获取数据并将数据传递到另一个流中。
具体如下:
let fs = require('fs')
let rs = fs.createReadStream('input.txt')
let ws = fs.createWriteStream('b.txt')
//管道读写操作
//读取input.txt文件内容,并写入到output中
rs.pipe(ws)
这个管道就是我们刚刚的输入输出流封装而成的一个管道