概念
Node.js 提供一组类似 UNIX(POSIX)标准的文件操作API。
const fs = require("fs");
- fs提供了同步、回调和基于promise的三种形式。同步api会阻塞线程,但对于某些场景,使用同步方法会更方便、更易理解
- 尽量使用promise方式,回调容易造成嵌套地狱
- 对于大文件,使用文件流的方式来读写文件 createReadStream 和 createWriteStream 来减少内存占用
- 三方npm包
fs-extra是fs的一个拓展,提供了很多更方便的api
打开文件
fs.open(path, flags[, mode], callback)
flags参数
用于描述打开文件的模式,例如r为读取模式、r+为读写模式等等
打开一个文件,若文件不存在,是报错还是新建,这些都可以通过该参数设置
文件描述符
一个文件描述是 open 以及 openSync 方法调用返回的一个数字。可用于操作文件,例如读、写等
const fd = fs.openSync('./file', 'a');
console.log(typeof fd === 'number'); // true
读写文件
readFile
fs.readFile('./file.txt',(err,data)=>{
if(err){
console.error(err);
return;
}
// 转换的是buffer,要用toString转换
console.log(data.toString());
});
read
const fs = require('fs')
fs.open('./file.text', 'r+', (err, fd) => { //flags: 'r+' 打开文件用于读写,修改文件时使用
if(err) {
console.error(err)
return
}
//创建一个buffer类型的变量content来存储读取到的数据
const content = Buffer.alloc(6)
fs.read(fd, content, 0, 6, 24, (err,bytesRead, buffer) => {
if(err) {
console.error(err)
return
}
//buff和字符串通过'+'拼接,会被转换为字符串,再去拼接
console.log('读取到的数据是:' + buffer)
})
})
readFileSync
const data = fs.readFileSync('./file.txt');
console.log(data.toString());
读写流
const fs = require('fs');
const readable = fs.createReadStream('./original.txt');
const writeable = fs.createWriteStream('./copy.txt');
readable.pipe(writeable);
逐行读取
const fs = require('fs');
const readline = require('readline');
const rl = readline.createInterface({
input: fs.createReadStream('/etc/hosts'),
crlfDelay: Infinity
});
rl.on('line', (line) => {
console.log(`cc ${line}`);
const extract = line.match(/(\d+\.\d+\.\d+\.\d+) (.*)/);
});
获取文件信息
通过异步的方式获取文件信息:
fs.stat('./file', (err,stats) => {
console.log(stats.isFile()); // 该文件是否是文件
})
文件锁
如果有多个进程操作同一文件,可能会造成文件信息错误,这时候就需要一个锁来保证文件操作的完整性
独占标记
// 所有需要打开文件的方法,fs.writeFile、fs.createWriteStream、fs.open 都有一个 x 标记
// 这个文件应该已独占打开,若这个文件存在,文件不能被打开
fs.open('config.lock', 'wx', (err) => {
if (err) { console.error(err); return;}
});
// 最好将当前进程号写进文件锁中
// 当有异常的时候就知道最后这个锁的进程
fs.writeFile(
'config.lock',
process.pid,
{ flags: 'wx' },
(err) => {
if (err) { console.error(err); return };
},
);
mkdir文件锁
独占标记有个问题,可能有些系统不能识别 0_EXCL 标记。另一个方案是把锁文件换成一个目录,PID 可以写入目录中的一个文件
fs.mkidr('config.lock', (err) => {
if (err) { console.error(err); return}
fs.writeFile(`/config.lock/${process.pid}`, (err) => {
if (err) { console.error(err); return }
});
});
watch文件
监听一个文件或目录,当它们发生改变时执行一定操作
const fs = require('fs');
fs.watch('./watchdir', console.log); // 稳定且快
fs.watchFile('./watchdir', console.log); // 跨平台