Notes
Node.js
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

在终端执行这段代码:

2

可以见得,该方法成功读取了这个文本文件,并返回了正确的值。

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); // 读取成功的结果
});

3

正如预期的,返回了错误对象以及不存在数据值。

判断文件是否读取成功

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

文件写入: 2

向 F盘 写入数据会导致失败,我们尝试一下:

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 中。

小明=90 小红=98 小绿=89 小兰=90

希望整理完毕后:

小明:90
小红:98
小绿:89
小兰:90

:::info 步骤分析

  1. 导入 fs 模块。
  2. 使用 readFile 方法读取文件。
  3. 判断读取成功与否。
  4. 处理成功读取的数据。
  5. 处理完的数据使用 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("写入成功");
  });
});

要点:

  • readFilewriteFile 的使用。
  • 字符串 split 操作。
  • replace 操作。

控制台输出结果:

分割后的数组 小明=90,小红=98,小绿=89,小兰=90
替换后的数组 小明:90,小红:98,小绿:89,小兰:90
处理后的字符串
小明:90
小红:98
小绿:89
小兰:90
写入成功

写入结果:

小明: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 返回结果:

console.log(__dirname);
node path

控制台返回结果:

D:\desk\FrontEnd\test\8-11

我们可以用它解决上面所说到的问题:

const fs = require('fs');
 
//highlight-start
fs.readFile(__dirname+'files/1.txt', 'utf8', function (err, dataStr) {
//highlight-end
    if (err) {
        // 如果读取失败返回错误信息
        console.log("读取失败"+ err.message);
    }
    else {
        // 如果读取成功返回数据
        console.log("读取成功" + dataStr);
    }
})