流式文件写入 & 读取
流式文件写入 / 读取适合操作大文件
流式写入
① 创建可写流:fs.createWriteStream(path[, options])
- path:文件路径
- options:配置对象- flags:文件系统标志,默认值为- 'w'
- encoding:数据的编码格式,默认为- utf8
 
- 返回值:WriteStream 对象
const fs = require('fs');
let ws = fs.createWriteStream('./WS.txt');
- 创建可写流后,可写流会自动开启,写入完成后需要手动关闭
② 写入数据:ws.write(data)
- data:需要写入的数据
const fs = require('fs');
let ws = fs.createWriteStream('./WS.txt');let content = '需要写入的内容';
ws.write(content);
ws.write('  追加的内容');
③ 通过监听流的 open 和 close 事件来监听流的开关
因为 open 和 close 操作都只会出现一次,所以这里使用 once() 绑定事件
const fs = require('fs');
const ws = fs.createWriteStream('./WS.txt');const content = '需要写入的内容';
ws.write(content);
ws.write('  追加的内容');// 监听 open 事件
ws.once('open', (_) => console.log('可写流打开了'));
// 监听 close 事件
ws.once('close', (_) => console.log('可写流关闭了'));
- 可以看见,只打印了 可写流打开了,因为可写流会自动开启,但不会自动关闭
④ 关闭可写流:ws.close([callBack]) / ws.end([callBack])
- callBack:回调函数,关闭可写流后调用;接收一个参数- err,默认为- null
const fs = require('fs');
const ws = fs.createWriteStream('./WS.txt');const content = '需要写入的内容';
ws.write(content);
ws.write('  追加的内容');ws.once('open', (_) => console.log('可写流打开了'));// 调用 close 方法关闭可写流
ws.close((_) => console.log('可写流关闭了'));
流式读取
① 创建可读流:fs.createReadStream(path)
- path:文件的路径
- 返回值:ReadStream 对象
const fs = require('fs');
let rs = fs.createReadStream('./WS.txt');
- 创建可读流后,可读流会自动开启。但此时还不会读取数据!
- 我们可以通过 rs.readableFlowing查看数据是否已经在读取:null-未读取、true-正在读取、false-读取完,已关闭
② 给可读流绑定一个 data 事件,绑定完毕后,会自动开始读取数据(每次最多读取 65536 byte)
回调函数接收一个参数 data,data 就是可读流传出的数据(二进制数据)
const fs = require('fs');
const rs = fs.createReadStream('./WS.txt');rs.on('data', (data) => {console.log('开始读取数据');console.log('data', data);
});
- 读取完后,可读流会自动关闭
③ 通过监听流的 open 和 close 事件来监听流的开关
因为 open 和 close 操作都只会出现一次,所以这里使用 once() 绑定事件
const fs = require('fs');
const rs = fs.createReadStream('./WS.txt');// 监听 open & close 事件
rs.once('open', (_) => console.log('readStream open!'));
rs.once('close', (_) => console.log('readStream close!'));rs.on('data', (data) => {console.log('开始读取数据');console.log('data', data);
});
demo:配合可写流使用
const fs = require('fs');
const rs = fs.createReadStream('./rs.txt');
const ws = fs.createWriteStream('./ws.txt');// 监听 data 事件,开启可读流
rs.on('data', (data) => {console.log('开始读取数据');console.log('data', data + ''); // 打印可读流里面的数据ws.write(data); // 写入读取到的数据
});// 监听可读流
rs.once('open', (_) => console.log('ReadStream open!'));
rs.once('close', (_) => {console.log('ReadStream close!');ws.end(); // 可读流关闭后,手动关闭可写流
});// 监听可写流
ws.once('open', (_) => console.log('WriteStream open!'));
ws.once('close', (_) => console.log('WriteStream close!'));
管道 pipe
pipe():可以将可读流中的数据,直接传到可写流中
const fs = require('fs');
const rs = fs.createReadStream('./WS.txt');
const ws = fs.createWriteStream('./123.txt');rs.pipe(ws); // 开启可读流,写入读取到的数据,写入完毕后自动关闭可写流// 监听可读流
rs.once('open', (_) => console.log('ReadStream open!'));
rs.once('close', (_) => console.log('ReadStream close!'));// 监听可写流
ws.once('open', (_) => console.log('WriteStream open!'));
ws.once('close', (_) => console.log('WriteStream close!'));
同步文件写入
openSync
① 打开文件:fs.openSync(path[, flags])
-  path:文件路径
-  flags:文件系统标志-  'r'(read):读取数据。如果文件不存在,则报错(默认)
-  'w'(write):写入数据。如果文件不存在,则创建该文件;否则覆盖文件原内容
-  'a'(add):追加数据。如果文件不存在,则创建该文件;否则追加内容
 
-  
返回值:表示文件描述符的整数 fd
const fs = require('fs');// 打开文件
const fd = fs.openSync('new.txt', 'w');
console.log('fd'); // fd 3
writeSync
② 写入内容:fs.writeSync(fd, data[, position[, encoding]])
- fd:表示文件描述符的整数
- data:需要写入的内容
- position:开始写入的位置(eg:- 2→ 空两位再开始写数据)
- encoding:写入的数据编码格式,默认为- utf8
- 返回值:写入的字节数
- 如果 data是普通的对象,则它必须具有自己的(不是继承的)toString方法
const fs = require('fs');const fd = fs.openSync('hello.txt', 'w');// 写入数据
const len = fs.writeSync(fd, 'hello superman');
console.log('len', len); // len 14
closeSync
③ 关闭文件:fs.closeSync(fd)
- fd:表示文件描述符的整数
const fs = require('fs');const fd = fs.openSync('hello.txt', 'w');
fs.writeSync(fd, 'hello superman');// 关闭文件
fs.closeSync(fd);
写入完成后,需要关闭文件,避免资源的浪费
异步文件写入
open
① 打开文件:fs.open(path[, flags], callback)
-  path:文件的路径
-  flags:文件系统标志-  'r'(read):读取数据。如果文件不存在,则报错(默认)
-  'w'(write):写入数据。如果文件不存在,则创建该文件;否则覆盖文件原内容
-  'a'(add):追加数据。如果文件不存在,则创建该文件;否则追加内容
 
-  
-  callBack:回调函数,打开文件后调用,接收 2 个参数:-  err:错误信息,默认为null
-  fd:表示文件描述符的整数
 
-  
const fs = require('fs');// 打开文件
fs.open('hello.txt','w',(_) => console.log(arguments) // [Arguments] { '0': null, '1': 3 }
);
write
② 写入数据:fs.write(fd, string[, position[, encoding]], callback)
-  fd:表示文件描述符的整数
-  string:需要写入的内容
-  position:开始写入的位置(eg:2 → 空两位再开始写数据)一般不写
-  encoding:写入的数据编码格式,默认为utf8,一般不写
-  callBack:回调函数,接收 3 个参数:-  err:错误信息,默认为null
-  len:写入的字节数
-  data:写入的数据内容
 
-  
const fs = require('fs');// 打开文件
fs.open('hello.txt', 'w', (err, fd) => {// 写入数据fs.write(fd, '异步写入的内容', (_) => {console.log(arguments); // [Arguments] { '0': null, '1': 21, '2': '异步写入的内容' }});
});
close
③ 关闭文件:fs.close(fd, callBack)
- fd:表示文件描述符的整数
- callBack:回调函数,接收 1 个异常参数- err,默认为- null
const fs = require('fs');// 打开文件
fs.open('hello.txt', 'w', function (err, fd) {if (err) return console.log('err', err);console.log('open');// 写入数据fs.write(fd, '异步写入的内容', (err) => {if (err) return console.log('err', err);console.log('write');// 关闭文件fs.close(fd, function (err) {if (err) return console.log('err', err);console.log('close');});});
});