[updated]Node.js学习笔记:fs模块实现文件读写

用node.js读写文件时,需要引入一个新的模块fs(file system文件系统)。文件系统的操作都有异步和同步的形式,案例使用异步方法,防止阻塞。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const fs = require('fs');

//1. 读取文件
fs.readFile('aaa.txt', function(err, data) {
if(err) {
console.log('读取失败');
} else {
//文件传输采用二进制,如果要输出为文字,需要使用toString()方法转换一下
console.log(data.toString());
}
})

//2. 写入文件
fs.writeFile('bbb.txt', 'hello world', function(err) {
console.log(err);
})
//这样就能改写bbb.txt内的内容,第二个参数为修改的内容
//如果没有bbb.txt文件,那么会创建一个新的bbb.txt文件,内容为第二个参数

文件读取可以配合http模块使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const http = require('http');
const fs = require('fs');

http.createServer(function(req, res) {
//在浏览器读取端口后,可在端口后添加新的请求的数据地址
//服务器可以通过req.url获取浏览器端输入的地址
//如浏览器端为localhost:8080/1.html, req.url就为1.html
//fileName为fs模块读取数据时的地址,需要考虑在本地的相对路径,例子中1.html在file文件夹下
let fileName = 'file/' + req.url;

fs.readFile(fileName, function(err, data) {
if(err) {
res.write('404');
} else {
//这里是服务器传递给浏览器的数据,不需要用toString()解析,浏览器会自行解析
//如果是直接用命令行输出,则需要解析,否则是二进制数据
res.write(data);
}
res.end();
})
}).listen(8080);

fs模块读取文件模型


2018/08/10 更新

fs模块的readFile方法是异步读取的,所以我们也可以结合ES6中提到的async函数来完成读取多个文件的操作。

  • 首先添加两个文件来给我们一会儿读取,我在根目录下添加了一个data文件夹,里面放了很简单的两个文件1.txt2.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const fs = require("fs");

// 1. 定义读取文件的函数,使之返回一个Promise对象
const readFile = function(fileName) {
return new Promise((resolve, reject) => {
fs.readFile(fileName, (err, data) => {
if(err) return reject(err);
resolve(data);
})
})
}
// 2. 将需要读取的文件用async函数的形式写出来
const asyncReadFile = async function() {
const f1 = await readFile('data/1.txt');
const f2 = await readFile('data/2.json');
console.log(f1.toString());
console.log(f2.toString());
}

// 3. async函数和generator函数的一大区别就是async函数可以直接调用
asyncReadFile();

读取结果:

image-20180810152207195


[2018/09/02 15:20 更新]

Node.js在进行异步操作时,传入的回调函数接受两个参数,一个是表示错误的err,正常读取时,err参数是null,另一个参数是data。如果发生了错误,err就代表一个错误对象,data就为undefined。这是Node.js的标准回调函数。

当我们使用fs模块读取文本信息时,data为读取到的string,如果我们读取的内容是图片,那么我们读取到的就是二进制文件,data就返回一个buffer对象。

我们也可以使用同步的方法读取文件。使用同步方法时,使用的方法会有一个Sync后缀,用来和异步方法区别开来。此外,同步的方法不接受回调函数,而是直接返回结果。

1
2
3
const fs = require("fs");
let data = fs.readFileSync("./data/1.txt", "utf-8");
console.log(data);

image-20180903153205803

如果同步读取文件发生错误,则需要使用try... catch来捕获错误。

1
2
3
4
5
6
try {
let data = fs.readFileSync("./data/1.txt", 'utf-8');
console.log(data);
} catch(err) {
console.log(err);
}

异步还是同步

关于实际运用中到底应该使用同步还是异步,由于JavaScript是单线程工作,绝大部分在服务器运行期要反复执行的代码都应该使用异步,否则同步执行期间,服务器将停止响应。

服务器启动时要读取的配置文件或者结束时需要写入到状态文件时,可以使用同步,因为这些代码在开始或结束时只执行一次。