文件系统模块

在Node中最常用的内建模块就是fs(表示 filesystem,文件系统)模块。该模块提供了处理文件和目录的函数。

例如,有个函数名为readFile,该函数读取文件并调用回调,并将文件内容传递给回调。

  1. let {readFile} = require("fs");
  2. readFile("file.txt", "utf8", (error, text) => {
  3. if (error) throw error;
  4. console.log("The file contains:", text);
  5. });

readFile的第二个参数表示字符编码,用于将文件解码成字符串。将文本编码成二进制数据有许多方式,但大多数现代系统使用 UTF-8,因此除非有特殊原因确信文件使用了别的编码,否则读取文件时使用"utf-8"是一种较为安全的方式。若你不传递任何编码,Node 会认为你需要解析二进制数据,因此会返回一个Buffer对象而非字符串。该对象类似于数组,每个元素是文件中字节(8 位的数据块)对应的数字。

  1. const {readFile} = require("fs");
  2. readFile("file.txt", (error, buffer) => {
  3. if (error) throw error;
  4. console.log("The file contained", buffer.length, "bytes.",
  5. "The first byte is:", buffer[0]);
  6. });

有一个名为writeFile的函数与其类似,用于将文件写到磁盘上。

  1. const {writeFile} = require("fs");
  2. writeFile("graffiti.txt", "Node was here", err => {
  3. if (err) console.log(`Failed to write file: ${err}`);
  4. else console.log("File written.");
  5. });

这里我们不需要制定编码,因为如果我们调用writeFile时传递的是字符串而非Buffer对象,则writeFile会使用默认编码(即 UTF-8)来输出文本。

fs模块也包含了其他实用函数,其中readdir函数用于将目录中的文件以字符串数组的方式返回,stat函数用于获取文件信息,rename函数用于重命名文件,unlink用于删除文件等。

而且其中大多数都将回调作为最后一个参数,它们会以错误(第一个参数)或成功结果(第二个参数)来调用。 我们在第十一章中看到,这种编程风格存在缺点 - 最大的缺点是,错误处理变得冗长且容易出错。

相关细节请参见http://nodejs.org/中的文档。

虽然Promise已经成为 JavaScript 的一部分,但是,将它们与 Node.js 的集成的工作仍然还在进行中。 从 v10 开始,标准库中有一个名为fs/promises的包,它导出的函数与fs大部分相同,但使用Promise而不是回调。

  1. const {readFile} = require("fs/promises");
  2. readFile("file.txt", "utf8")
  3. .then(text => console.log("The file contains:", text));

有时候你不需要异步,而是需要阻塞。 fs中的许多函数也有同步的变体,它们的名称相同,末尾加上Sync。 例如,readFile的同步版本称为readFileSync

  1. const {readFileSync} = require("fs");
  2. console.log("The file contains:",
  3. readFileSync("file.txt", "utf8"));

请注意,在执行这样的同步操作时,程序完全停止。 如果它应该响应用户或网络中的其他计算机,那么可在同步操作中可能会产生令人讨厌的延迟。