理解node中文件readable.read()方法和引发的思考与总结
-
首先,我们来看看readable事件,‘data’、'readable’的区别
-
总结:
-
‘data’:即流模式,即读取数据后会自动调用readable.read()方法,然后将chunk(默认buffer)通过事件驱动传入回调函数
-
‘readable’:即暂停模式,顾名思义,调用需要咱们手动掉,就像开关,我们需要readable.read()消费数据,每次读取highWaterMark大小的数据载入缓存,全部消费完毕就会再次去读触发’readable’回调
- 读到最后:
- 如果最后部分数据少于readable.read(size),返回null,再次调用’readable’返回null确认没有数据了,再次调用’readable’才输出最后的部分
- 如果最后数据等于readable.read(size)返回读取到的数据,再次调用’readable’确认没有了输出null
-
// copy.txt
0123456789
// source.js
/**
* @file: 26.fs-createStream.js
* @author: xiaoqinvar
* @desc:fs可读流应用
* @date: 2022-06-26 15:44:31
*/
const { createReadStream } = require('fs');
const rs = createReadStream('../assets/copy.txt', {
highWaterMark: 8, // 一次读取8字节的buffer,
flags: 'r', // 默认,r:读取操作
encoding: null, // 读取编码,默认二进制buffer
fd: null, // 文件标识符
mode: 0o666, // 文件模式:全权限模式
autoClose: true, // 读取完毕 or 发生错误自动关闭
start: 0, // 开始读取的位置0默认开头,没有指定end即读取所有
});
// 流模式
/* rs.on('data', (chunk) => {
console.log(chunk);
console.log(chunk.toString());
}); */
// 流模式输出结果:
// 执行流程:一次性读取8个字节到缓存,然后自动帮我们调用readable.read(),即进入'data'回调
/*
<Buffer 30 31 32 33 34 35 36 37>
01234567
<Buffer 38 39>
89
*/
-
暂停模式
// copy.txt 12345678 // source.js rs.on('readable', () => { console.log(' ---- read ----'); let data; while ((data = rs.read(2)) !== null) { console.log('链表头部', rs._readableState.buffer.head); console.log(data.toString()); } console.log('data的值: ', data); console.log(' ---- end ----'); }); // 读取完毕会触发 rs.on('end', () => { console.log('file had been read'); }); // 可读流关闭触发 rs.on('close', () => { console.log('stream had been closed'); }); // 暂停模式输出结果: // 执行流程:一次性读取8个字节到缓存 -> 调用'readable'回调 -> 消费完毕 -> 重复操作 /* ---- read ---- 链表头部 { data: <Buffer 33 34 35 36 37 38>, next: null } 12 链表头部 { data: <Buffer 35 36 37 38>, next: null } 34 链表头部 { data: <Buffer 37 38>, next: null } 56 链表头部 null 78 data的值: null ---- end ---- // 这里就是上面的结论,没有即再次确认 ---- read ---- data的值: null ---- end ---- // 读取结束 file had been read // 关闭流 stream had been closed */
你可以验证其他两个结论
修改
copy.txt
为123456789
,最后会执行一次’readable’返回null,再执行一次’readable’返回剩余部分9
的字符