fs 即文件系统
通过require 使用该模块:
const fs = require('fs');
所有文件系统操作都具有同步和异步的形式。【推荐异步】
异步的形式总是将完成回调作为其最后一个参数。 传给完成回调的参数取决于具体方法,但第一个参数始终预留用于异常。 如果操作成功完成,则第一个参数将为 null
或 undefined
。
首先,我们看一看最简单的例子,读文件。【可以看到是Buffer对象】
const fs = require('fs');
fs.readFile('./fsTest.js', (err, data) => {
if (err) throw err;
console.log(data.toString());
});
下面,我们设置一下,使得读取按 utf8 编码。
const fs = require('fs');
fs.readFile('./fsTest.js', 'utf8', (err, data) => {
if (err) throw err;
console.log(data.toString());
});
同时,readFile 的同步操作 readFileSync ,如下。
const fs = require('fs');
const data = fs.readFileSync('./fsTest.js', 'utf8');
console.log(data);
然后,我们看一看写文件。
const fs = require('fs');
fs.writeFile('./text', "This is a test", {
encoding: "utf8"
}, err => {
if (err) throw err;
console.log("Done!");
})
接下来,文件信息 fs.stat()
const fs = require('fs');
fs.stat('./123text', (err, stat) => {
if (err) {
console.log("文件不存在。");
throw err;
}
console.log(stat.isFile());
console.log(stat.isDirectory());
console.log(stat);
})
我们判断一个文件是否存在,推荐使用fs.stat()。如果返回err 那就是不存在这个文件。
然后,我们再看一看fs.rename()
const fs = require('fs');
fs.rename('./text','./test.txt', err => {
if (err) throw err;
})
删除文件 fs.unlink()
const fs = require('fs');
fs.unlink('./test.txt', err => {
if (err) throw err;
})
下面来看一下文件夹的操作。
读文件夹下的所有文件:
const fs = require('fs');
fs.readdir('./', (err, files) => {
if (err) throw err;
console.log(files);
})
创建一个文件夹:
const fs = require('fs');
fs.mkdir('test', err => {
if (err) throw err;
})
删除一个文件夹:
const fs = require('fs');
fs.rmdir('./test', err => {
if (err) throw err;
})
监视一个文件/目录 fs.watch():【在构建项目的时候会用到这个】
其中 recursive 表示是否要循环监控目录下的目录。
const fs = require('fs');
fs.watch('./',{
recursive: true
}, (eventType,filename) => {
console.log(eventType, filename);
})
然后去操作一下就会打印出来:
之前我们对文件的操作,都是把它读取到内存中然后进行一些操作。除了放内存中外,我们还可以放在stream(流) 中。放在流中,就可以用流的方式读取。
http://nodejs.cn/api/stream.html
pipe() 是将stream 中的数据输出的时候用的,读一部分数据就可以写一部分数据。
process.stdout 就是控制台。
const fs = require('fs');
const rs = fs.createReadStream('./fsTest5.js');
rs.pipe(process.stdout);
write() 是生产一部分数据就写一部分数据。
const fs = require('fs');
const ws = fs.createWriteStream('./test.txt');
const tid = setInterval( () => {
const number = parseInt( Math.random() * 10 );
console.log(number);
if (number < 8) {
ws.write(number + '');
} else {
clearInterval(tid);
ws.end();
}
}, 200);
ws.on('finish', () => {
console.log('Done.');
})
当我们使用异步函数的时候,可能异步函数里面调用异步函数,这个异步函数里面,又调用了异步函数...
这就是回调地狱。类似这样:
() => {
() => {
() => {
}
}
}
如果更复杂的,我们可以使用promise 类的语法,使得异步调用的写法接近同步的写法。如下
promisify 可以参考:(http://nodejs.cn/api/util.html)
const fs = require('fs');
const promisify = require('util').promisify;
const read = promisify(fs.readFile);
read('./fsTest6.js',{encoding: 'utf8'}).then(data => {
console.log(data);
}).catch(ex => {
console.log(ex);
})
或者使用 async 语法
const fs = require('fs');
const promisify = require('util').promisify;
const read = promisify(fs.readFile);
async function test () {
try {
const data = await read('./fsTest7.js');
console.log(data.toString());
} catch (ex) {
console.log(ex);
}
}
test();