上文中我们所说的文件的增删改查处理都是直接打开完整的文件,此种方式在遇到大文件读写时性能问题较大,但除了这种方式还有其他的方式来处理,可以使用流的方式来对文件进行分片处理。下面来介绍下nodejs中这种处理方式。
文件流
前文已经说明nodejs中的文件流是对文件的分片处理,文件流也可以说是另一种读写文件的方式,更加适用于大文件的处理,目的是为了节省IO的内存使用率。
nodejs的文件流
- 可读流(Readable):数据从源头流向内存,把磁盘里面的数据传输到内存里面,即数据读取。
- 可写流(Writable):写入一个数据,可以将字符串或buffer写入文件,即数据写入。
网络异常,图片无法展示
|
流的使用api
nodejs中文件流的操作主要是stream模块,其内部实现了两个类可读流(Readable)和可写流(Writable)。另外文件流的基础实现是事件流机制。
- 创建可读流:fs.createReadStream(filePath,{options}),返回一个可读流对象,该对象可以用来操作文件流以及监听文件流的传输,options中有以下参数可以设置:
- flag: 'r',
- encoding: null, // 设置编码方式
- fd: null,
- mode: 438, // 十进制
- start: number, // 设置可读流的开始读取位置
- end: number, // 设置可读流的结束读取位置
- highWaterMark: number(kb) // 每个chunk的最大体积
const filename=__dirname+'/demo.json'; //highWaterMark 设置 const readStream = fs.createReadStream(fileName,{highWaterMark:1}); let data = '' //监听文件流传输 readStream.on('data',(chunk)=>{ console.log('=========') data = data + chunk; }) readStream.on('end',(chunk)=>{ console.log('file read end') }) readStream.on('error',(err)=>{ console.log(err) })
- 创建可写流:fs.createWriteStream(filePath,options),返回一个可写流对象,options中的参数和可读流一样。
const fileWriteName = __dirname + '/fsdir2/demo2.txt'; const writeStream = fs.createWriteStream(fileWriteName); //写入数据 writeStream.write("0000", () => { console.log('数据写完了000') }) //监听写入关闭的操作 writeStream.on('close', (fd) => { console.log('文件关闭了', fd) }) writeStream.end() //监听文件写入完成 writeStream.on('end', () => { console.log('当数据被清空之后') })
- 管道的使用:以上的可读和可写流可以看出我们传递数据虽然被转换成了流,但仍然需要获取到文件的所有内容才能继续进行,当我们使用管道就不会遇到此问题,下面看一个文件复制的例子:
网络异常,图片无法展示
|
const filename=__dirname+'/demo/demo.txt'; const readStream = fs.createReadStream(filename,{highWaterMark:1}); const fileWriteName = __dirname + '/demo/demo2.txt'; const writeStream = fs.createWriteStream(fileWriteName); //直接通过管道传输流不用一次性传输了 readStream.pipe(writeStream) 复制代码
总结
文件使用流的方式处理已经深入服务器中,这种方式能大大的提升系统的性能以及可用率。普通方式的处理个人也会经常使用在一些小文件的脚本处理。文件各种的处理方式大家应当在合适的场景应用合适的方式。