fs 文件系统模块
fs 模块是 Node 提供的用来操作文件的模块。用来满足对文件操作的需求。
fs.readFile()
方法,读取指定文件的内容。fs.writeFile()
方法,向指定文件写入内容。
导入
fs 文件模块是 Node 自带的模块,因此只要导入模块即可。
const fs=require('fs');
读取指定文件的内容
语法格式
fs.readFile(path [, options],callback);
参数解读:
path
: 必选参数。字符串,标明文件的路径。options
: 可选参数。标识编码格式。callback
: 必选参数,文件读取完成后要执行的回调函数。
示例代码
使用 utf8
编码格式读取指定文件的内容,并打印 err 和 dataStr 的值。
const fs=require('fs');
fs.readFile('./files/11.txt','utf8',function(err,dataStr){
// 无论是否读取成功都会执行回调函数,这整个函数作为参数
console.log(err);
console.log('----');// 分割线
console.log(dataStr);// 读取成功的结果
})
用 VScode 创建一个工程。
创建 api.js 文件,内容如下:
const fs = require("fs");
fs.readFile("11.txt", "utf8", function (err, dataStr) {
// 无论是否读取成功都会执行回调函数,这整个函数作为参数
console.log(err);
console.log("----"); // 分割线
console.log(dataStr); // 读取成功的结果
});
在同层级目录下创建文件 11.txt
:
1111
在终端执行这段代码:
可以见得,该方法成功读取了这个文本文件,并返回了正确的值。
null
----
1111
因为没有发生错误,所以 err 参数值为 null 。
我们不妨试一下,让这段代码读取不存在的文件。这次应该会有 err 报错。
const fs = require("fs");
fs.readFile("no.txt", "utf8", function (err, dataStr) {
// 无论是否读取成功都会执行回调函数,这整个函数作为参数
console.log(err);
console.log("----"); // 分割线
console.log(dataStr); // 读取成功的结果
});
正如预期的,返回了错误对象以及不存在数据值。
判断文件是否读取成功
const fs = require('fs');
fs.readFile('11.txt', 'utf8', function (err, dataStr) {
if (err) {
// 如果读取失败返回错误信息
console.log("读取失败"+ err.message);
}
else {
// 如果读取成功返回数据
console.log("读取成功" + dataStr);
}
})
成功状态执行结果:
读取成功1111
失败返回结果:
读取失败ENOENT: no such file or directory, open 'D:\desk\FrontEnd\test\8-11\111.txt'
向指定文件写入内容
语法格式
fs.readFile(path , data , [, options], callback);
参数解读:
path
: 必选参数。字符串,标明文件的路径。data
: 必选参数,写入的内容。options
: 可选参数。标识编码格式。callback
: 必选参数,文件读取完成后要执行的回调函数。
示例代码
const fs = require("fs");
fs.writeFile("22.txt", "HelloWorld", "utf8", function (err) {
console.log(err);
});
写入成功,返回值:
null
文件写入:
向 F盘 写入数据会导致失败,我们尝试一下:
writefail.js
const fs = require("fs");
fs.writeFile("f:/11.txt", "HelloWorld", "utf8", function (err) {
console.log(err);
});
执行:
node writefail.js
结果:
[Error: ENOENT: no such file or directory, open 'f:\11.txt'] {
errno: -4058,
code: 'ENOENT',
syscall: 'open',
path: 'f:\\11.txt'
}
判断文件是否写入成功
fs.writeFile("f:/11.txt", "HelloWorld", "utf8", function (err) {
if (err) {
return console.log("写入失败" + err.message);
}
console.log("写入成功");
});
返回结果同样是写入失败。
练习-1
使用 fs 系统模块,将 成绩.txt
中的考试数据整理到 成绩-ok.txt
中。
成绩.txt
小明=90 小红=98 小绿=89 小兰=90
希望整理完毕后:
成绩-ok.txt
小明:90
小红:98
小绿:89
小兰:90
步骤分析
- 导入 fs 模块。
- 使用
readFile
方法读取文件。 - 判断读取成功与否。
- 处理成功读取的数据。
- 处理完的数据使用
writeFile
方法写入新文件。
node 代码:
const fs = require("fs");
fs.readFile("成绩.txt", "utf8", function (err, dataStr) {
// 判断是否读取成功
if (err) {
return console.log("抱歉,数据请求失败 " + err.message);
}
// 读取成功
// console.log("获得成绩列表" + dataStr);
// 分割数据,使用 split 按照空格为分隔符划分
const arrOld = dataStr.split(" ");
console.log("分割后的数组 " + arrOld);
// 创建新的数组
const arrNew = [];
// 执行循环遍历数组,替换 = 为 :
arrOld.forEach((item) => {
arrNew.push(item.replace("=", ":"));
// push 操作加入新数组中,并将每个元素的 = 替换成 :
});
console.log("替换后的数组 " + arrNew);
// 合并成新数组
const resStr = arrNew.join("\r\n");
//在每个数组元素之间添加换行符号
console.log("处理后的字符串\n" + resStr);
fs.writeFile("成绩-ok.txt", resStr, function (err) {
if (err) {
return console.log("写入错误");
}
console.log("写入成功");
});
});
要点:
readFile
和writeFile
的使用。- 字符串
split
操作。 replace
操作。
控制台输出结果:
分割后的数组 小明=90,小红=98,小绿=89,小兰=90
替换后的数组 小明:90,小红:98,小绿:89,小兰:90
处理后的字符串
小明:90
小红:98
小绿:89
小兰:90
写入成功
写入结果:
成绩-ok.txt
小明:90
小红:98
小绿:89
小兰:90
路径动态拼接
问题产生
在操作文件时候,如果操作的路径是 ./
或者 ../
等前缀的相对路径的时候,很容易出现动态路径的拼接错误。在执行代码的时候 node 是通过 node 脚本所处的目录动态拼接的。
const fs = require('fs');
fs.readFile('./files/1.txt', 'utf8', function (err, dataStr) {
if (err) {
// 如果读取失败返回错误信息
console.log("读取失败"+ err.message);
}
else {
// 如果读取成功返回数据
console.log("读取成功" + dataStr);
}
})
但是如果你此时 cd 了上一层的目录,这时你的 node 脚本会按照你 cd 的目录作为前缀拼接,很遗憾,上一层目录是不能访问到这个 file 文件夹的,文件会读取失败。
问题解决
- 结果这个问题的第一个方法就是提供一个完整的文件路径。但是移植性差,不易于维护。
- 第二个方法:使用
__dirname
访问路径。
我们测试一下 __dirname
返回结果:
path.js
console.log(__dirname);
node path
控制台返回结果:
D:\desk\FrontEnd\test\8-11
我们可以用它解决上面所说到的问题:
const fs = require('fs');
fs.readFile(__dirname+'files/1.txt', 'utf8', function (err, dataStr) {
if (err) {
// 如果读取失败返回错误信息
console.log("读取失败"+ err.message);
}
else {
// 如果读取成功返回数据
console.log("读取成功" + dataStr);
}
})