Kodokon kodokon.com

文件系统:用 fs/promises 读取和写入

你将用 fs/promises 模块读取和写入文件,并借助 path 模块构建可靠的路径。

8 分钟 · 3 题

在 Kodokon 中打开本课

在浏览器里,JavaScript 不被允许触碰你磁盘上的文件:这是出于安全考虑。而 Node 则直接运行在你的机器上,多亏了 fs 模块(file system,即文件系统),它能够读取和写入文件。我们会使用它的现代版本 fs/promises,它的每个函数都返回一个 Promise,你已经知道该如何用 await 来等待它们了,这在 JavaScript 课程里见过。请注意导入语句里的 node: 前缀:它清楚地表明这个模块来自 Node 本身,而不是来自 node_modules。还有个好消息:在 ES 模块里,await 可以直接在文件顶层使用,无需外面再包一个函数。

JAVASCRIPT
import { writeFile } from "node:fs/promises";

await writeFile("notes.txt", "First note\n");
console.log("File created!");
如果 notes.txt 文件不存在,writeFile 就会用作为第二个参数给出的文本来创建它。

要读取文件,用 readFile,逻辑是一样的。它的第二个参数很关键:utf8 指定了编码,也就是把磁盘上存储的字节翻译成可读文本的方式。如果你省略它,Node 会返回一个 Buffer 对象(原始字节),而不是一个字符串。

JAVASCRIPT
import { readFile } from "node:fs/promises";

const text = await readFile("notes.txt", "utf8");
console.log(text);
文件的内容会以字符串的形式到来,随时可以进行处理。

来聊聊路径相对路径(notes.txtdata/log.txt)从当前文件夹出发;绝对路径(C:\.../home/...)从磁盘的根目录出发。一个经典的陷阱:Windows 用 \ 分隔文件夹,而 macOS 和 Linux 用 /path 模块解决了这个问题:无论在什么系统上,path.join 都会用正确的分隔符把各个部分拼接起来。让我们把它和用来创建文件夹的 mkdir 结合起来使用。

JAVASCRIPT
import path from "node:path";
import { mkdir, writeFile } from "node:fs/promises";

const file = path.join("data", "log.txt");

await mkdir("data", { recursive: true });
await writeFile(file, "First log\n");
console.log("Written to:", file);
recursive 选项可以避免在 data 文件夹已存在时报错。

知识检测

确认你已牢记本课的重点内容。

  1. 如果你省略第二个 utf8 参数,readFile 会返回什么?
    • 一个空字符串
    • 一个错误:编码是必填的
    • 一个 Buffer,也就是文件的原始字节
  2. 如果目标文件已经存在,writeFile 会怎么做?
    • 它用新文本替换掉全部已有的内容
    • 它把新文本添加到文件的末尾
    • 它拒绝写入并抛出一个错误
    • 它会自动创建一份备份
  3. 用 path.join 来构建路径有什么好处?
    • 它会创建路径中缺失的文件夹
    • 它会用适合当前系统的分隔符把各个部分拼接起来
    • 它会在继续之前检查文件是否存在