Skip to content

内置模块与本地仓库操作(Day6 3/3) ​

本页对应 Day06_Node,共 5 段视频,约 1 小时 17 分。

学习目标 ​

  • 能够使用 require 引入 path、fs 等内置模块,并用变量接收模块对象后调用其方法。
  • 能够使用 path.join、path.resolve、path.dirname、path.basename、path.extname、path.isAbsolute 完成路径拼接、解析、拆解和绝对路径判断,并说明跨平台路径分隔符差异。
  • 能够使用 fs.readFile / fs.readFileSync 读取文件内容,正确指定编码或调用 toString() 转换 Buffer,并通过错误对象或 try...catch 处理读取异常。
  • 能够使用 fs.writeFile / fs.writeFileSync 写入文件,区分覆盖写入与 fs.appendFile / fs.appendFileSync 追加写入,并处理写入失败。
  • 能够使用 fs.rename / fs.renameSync 完成文件重命名,并利用完整路径变化实现文件位置移动。
  • 能够使用 fs.unlink / fs.unlinkSync 删除指定文件,并对文件不存在等异常情况给出正确判断和处理。

知识点 ​

模块引入:先 require,再使用 ​

为什么需要:Node 中模块分为内置模块、第三方模块和自定义模块。无论哪一种,使用时都要先引入;不引入就直接调用其中的方法会报错。
怎么想:先明确要用哪个模块,再查官方文档确认模块名和方法,最后用 require 引入。require 的参数是模块名字符串,返回值是一个对象,变量名可以自定义,但一般与模块同名,便于阅读。
怎么做:

js
const path = require('path')
const fs = require('fs')

易错点:不要把变量名当成固定语法;require('path') 不能写成 require(path)。引入后得到的是模块对象,方法要通过对象调用,如 path.join()、fs.readFile()。

path 模块:拼接、判断与拆解路径 ​

为什么需要:手写路径分隔符容易出问题。Windows 使用反斜杠,Linux、macOS 等类 Unix 系统使用正斜杠;代码可能在本机开发、在服务器运行,所以要用 path 处理路径。
怎么想:拼接路径不要用字符串加号硬拼,优先用 path.join();需要把相对路径转成绝对路径时用 path.resolve();判断是否绝对路径用 path.isAbsolute();拆目录、文件名、扩展名分别用 dirname、basename、extname。
怎么做:

js
const path = require('path')
console.log(path.join('images', 'data')) // 按当前系统分隔符拼接
console.log(path.resolve('./images/data')) // 转成绝对路径
console.log(path.isAbsolute(__filename)) // true
console.log(path.dirname(__filename)) // 当前脚本所在目录
console.log(path.basename(__filename)) // 当前脚本文件名
console.log(path.extname(__filename)) // .js

易错点:join 主要是纯拼接,不保证结果是绝对路径;resolve 会基于当前脚本所在目录把相对路径转成绝对路径。转写稿中调试时曾把 __filename 拼进路径,结果路径指到脚本文件后再拼 data,明显不对;后来改用 __dirname 才正确。join 拼接结果的分隔符会随操作系统变化,这正是它比手写斜杠更稳妥的原因。

fs 读取文件:异步优先,注意 Buffer 与错误 ​

为什么需要:fs 是文件系统模块,用来读写文件和目录。读取文件时,Node 提供同步和异步两种方式;异步不会阻塞后续代码,更适合服务器场景。
怎么想:优先用异步 readFile;回调函数第一个参数是错误对象 err,第二个参数是数据 data。如果不指定编码,data 是 Buffer,需要 toString() 或读取时指定 utf8。路径建议用 path.join(__dirname, ...) 拼成绝对路径,更稳。
怎么做:

js
const fs = require('fs')
const path = require('path')
const fileName = path.join(__dirname, 'data', 'a.txt')

fs.readFile(fileName, 'utf8', (err, data) => {
  if (err) {
    console.log('文件读取失败', err.errno, err.code)
    return
  }
  console.log('文件读取成功', data)
})

同步写法用 readFileSync,并配合 try/catch:

js
try {
  const data = fs.readFileSync(fileName, 'utf8')
  console.log(data)
} catch (err) {
  console.log('文件读取失败', err.errno, err.code)
}

易错点:异步回调里判断 err 后要 return,否则失败后仍可能继续执行成功逻辑;不指定编码会读到 Buffer;路径拼错时 err 是对象,可查看 errno 和 code。转写稿中还演示了错误路径下输出“文件读取失败”,说明错误处理要放在回调内部。

fs 写入文件:writeFile 覆盖,appendFile 追加 ​

为什么需要:实际开发中要保存日志、生成文件、写临时数据。writeFile 用于写入,appendFile 用于追加。
怎么想:先明确是覆盖还是追加。writeFile 在文件不存在时会创建,文件已存在时会覆盖原内容;appendFile 则在原内容后追加。异步回调只接收一个 err 参数。
怎么做:

js
const fs = require('fs')
const path = require('path')
const fileName = path.join(__dirname, 'data', 'b.txt')
const content = '你好,小乐\n'

fs.writeFile(fileName, content, (err) => {
  if (err) {
    console.log('写入失败', err.errno, err.code)
    return
  }
  console.log('写入成功')
})

fs.appendFile(fileName, content, (err) => {
  if (err) {
    console.log('追加失败')
    return
  }
  console.log('追加成功')
})

同步写入可用 writeFileSync、appendFileSync,并用 try/catch 包裹。
易错点:writeFile 不是追加,重复运行会覆盖;文件不存在时通常会创建,所以“写不进去”更可能是路径拼错。转写稿中写入失败就是路径拼接有问题,输出文件名后发现拼错,改用 __dirname 或 path.resolve 后成功。Buffer 写入也会按编码处理,例如写入数字 100,显示为字母 d,因为 100 是字符 d 的编码。

为什么需要:文件管理常涉及改名、移动位置和删除。rename 可改文件名,也可改变完整路径,因此能移动文件;unlink 用于删除文件。
怎么想:从编程角度看,文件名是完整路径的一部分,rename(oldPath, newPath) 改的是完整路径,所以既能重命名也能移动。删除用 unlink(path, callback)。二者都有同步版本。
怎么做:

js
const fs = require('fs')
const path = require('path')

const oldPath = path.join(__dirname, 'data', 'a.txt')
const newPath = path.join(__dirname, 'data', 'a.md')

fs.rename(oldPath, newPath, (err) => {
  if (err) {
    console.log('重命名失败', err.errno, err.code)
    return
  }
  console.log('重命名成功')
})

fs.unlink(newPath, (err) => {
  if (err) {
    console.log('删除失败', err.errno, err.code)
    return
  }
  console.log('删除成功')
})

易错点:重复运行重命名会失败,因为旧文件已不存在;重复删除也会失败。异步回调中失败后要 return。同步版本如 renameSync、unlinkSync 可配合 try/catch,但实际开发仍优先考虑异步,避免阻塞。

从“查文档 + 引入模块”开始 ​

本节从 Node.js 内置模块 path 和 fs 入手,完成本地文件的路径处理、读取、写入、重命名与删除。为什么需要先讲这些?因为文件操作离不开路径,而不同操作系统对路径分隔符的处理并不一样;如果手写字符串拼接,很容易在 Windows 与 Linux 之间出现兼容问题。怎么想?先把“路径处理”和“文件读写”分开:path 负责算路径,fs 负责真正读写文件。怎么做?使用内置模块前必须先引入,并用变量保存模块对象:

js
const path = require('path');
const fs = require('fs');

require 的参数是模块名,返回值是模块对象。易错点:模块不引入就不能用;变量名可以自定义,但通常写成 path、fs 便于阅读。转写稿里反复提到“pass”,实际是 path;“照/周义/周尾”是 path.join,“resso”是 path.resolve。

path.join:拼接路径,自动适配系统分隔符 ​

为什么需要 path.join?因为路径拼接不是简单加字符串。怎么想?把多个路径片段交给它,它会按当前系统规则拼接,并处理多余分隔符。怎么做:

js
const p1 = path.join('image', 'data');
const p2 = path.join(__dirname, 'data', 'a.txt');
console.log(p1, p2);

转写稿中演示了 path.join(__dirname, 'data', 'a.txt'),输出会是当前脚本所在目录下的完整路径。易错点:__filename 是当前脚本文件的完整路径,不是目录;拼同级目录要用 __dirname。转写稿里写入文件失败,正是因为把 __filename 当成目录继续拼 data/b.txt,结果拼到了 02-写入文件.js/data/b.txt 这种错误位置。调试时先 console.log(fileName) 看拼出来的路径,再改成 __dirname 或 path.resolve。

path 的其他常用方法 ​

为什么还要 isAbsolute、dirname、basename、extname?因为实际开发经常要判断和拆解路径。怎么想?把完整路径拆成“目录、文件名、扩展名”分别处理。怎么做:

js
console.log(path.isAbsolute('a.jpg'));        // false
console.log(path.isAbsolute(__filename));     // true
console.log(path.dirname(__filename));        // 目录部分
console.log(path.basename(__filename));       // 文件名部分
console.log(path.extname(__filename));        // .js

易错点:isAbsolute 返回布尔值;basename 只取最后一段文件名,不包含目录。path.resolve 则会把相对路径转成绝对路径,并基于当前脚本所在目录解析:

js
console.log(path.resolve('./image/data'));

它和 join 的区别是:join 主要做拼接,resolve 会得到绝对路径。转写稿建议:不确定路径时,用 path.resolve 把相对路径转绝对路径,准确性和稳定性更好。

fs.readFile:异步读取文件 ​

为什么读取文件要用 fs?因为 fs 是文件系统模块,能读写文件和目录。怎么想?读取分同步和异步,推荐异步,避免阻塞后续代码。怎么做:

js
const fs = require('fs');
const path = require('path');

const fileName = path.join(__dirname, 'data', 'a.txt');

fs.readFile(fileName, 'utf8', (err, data) => {
  if (err) {
    console.log('文件读取失败', err.code, err.errno);
    return;
  }
  console.log(data);
});

转写稿先演示了不传编码时得到 Buffer,再用 data.toString() 转字符串;更推荐第二个参数直接写 'utf8'。易错点:回调第一个参数是错误对象,第二个才是数据;err 为空表示成功。若出错后不 return,后面的成功逻辑还可能继续执行。

fs.readFileSync 与 try/catch ​

同步读取为什么还要了解?有些场景需要按顺序立即拿到结果。怎么做:

js
try {
  const data = fs.readFileSync(fileName, 'utf8');
  console.log(data);
} catch (err) {
  console.log('文件读取失败', err.code, err.errno);
}

易错点:同步会阻塞后续代码;同步读取失败通常要用 try/catch 捕获。转写稿强调:推荐异步,但同步方式要会看、会写。

fs.writeFile:写入会覆盖原内容 ​

为什么用 writeFile?因为它能把字符串或 Buffer 写入文件。怎么做:

js
const fileName = path.join(__dirname, 'data', 'b.txt');
const content = '你好,小乐儿\n';

fs.writeFile(fileName, content, (err) => {
  if (err) {
    console.log('写入失败', err.code, err.errno);
    return;
  }
  console.log('写入成功');
});

易错点:文件不存在时会自动创建;文件已存在时会覆盖原内容,不是追加。转写稿中还演示了写入 Buffer,数字 100 最终显示为字母 D,因为写入时会按编码处理。

fs.appendFile:追加写 ​

为什么需要追加?因为 writeFile 会覆盖。怎么做:

js
fs.appendFile(fileName, '追加一行\n', (err) => {
  if (err) {
    console.log('写入失败');
    return;
  }
  console.log('写入成功');
});

同步追加可用 fs.appendFileSync。转写稿用循环追加一千行、一万行,说明追加不会清空原文件。易错点:追加写仍要判断 err。

fs.rename(oldPath, newPath, callback) 既能重命名,也能移动文件位置,因为完整文件名包含路径。转写稿把 data/a.txt 改成 a.md,又把文件移动到外层目录,均成功。易错点:旧路径不存在会失败。

删除用 fs.unlink(filePath, callback):

js
fs.unlink(path.join(__dirname, 'a.md'), (err) => {
  if (err) {
    console.log('文件删除失败');
    return;
  }
  console.log('文件删除成功');
});

易错点:第一次删除成功后,第二次再运行会失败,因为文件已不存在。rename、unlink 也都有同步版本,如 renameSync、unlinkSync。整体原则:能用异步就用异步;路径优先用 path.join 或 path.resolve 生成绝对路径,出错时先打印路径和错误对象再排查。

材料说明与本节范围 ​

给定笔记标题是“2 远程仓库有关的操作”,但转写稿实际讲解的是 Node.js 内置模块 path 与 fs 的文件操作,并没有出现远程仓库相关内容。为避免编造,下面按转写稿整理本节教程正文;远程仓库部分因材料缺失不补写。转写稿中也没有可保留的图片,故只整理其中的代码与调试过程。

path 模块:先引入再使用 ​

为什么需要:路径拼接不能直接靠字符串加号,因为 Windows 用反斜杠、Linux/macOS 用正斜杠,写死分隔符容易在部署后出错。
怎么想:内置模块要先 require 引入,拿到模块对象后再调用方法。
怎么做:

js
const path = require('path')

const filename = path.join(__dirname, './data/a.txt')
console.log(filename)

易错点:require('path') 不能漏;变量名可自定义,但一般用 path。path.join 是纯拼接,不会自动变成绝对路径;path.resolve 才会把相对路径解析成绝对路径。path.isAbsolute 判断是否绝对路径;path.dirname、path.basename、path.extname 分别取目录、文件名、扩展名。

fs 读取文件:异步优先,注意 Buffer 与错误对象 ​

为什么需要:读文件需要时间,同步读取会阻塞后续代码;异步读取把回调放入回调队列,等同步任务执行完再执行。
怎么想:先拼绝对路径,再用 fs.readFile;回调第一个参数是错误对象,第二个是数据。
怎么做:

js
const fs = require('fs')
const path = require('path')

const filename = path.join(__dirname, './data/a.txt')

fs.readFile(filename, 'utf8', (err, data) => {
  if (err) {
    console.log('文件读取失败', err.errno, err.code)
    return
  }
  console.log(data)
})

转写稿中的调试过程是:不指定编码时读到的是 Buffer,直接打印会出现二进制内容,需要 data.toString() 或传 'utf8'。文件地址写错时,err 是对象,可取 errno 和 code;加 return 可避免错误后继续执行。同步读取用 fs.readFileSync,出错时用 try/catch 捕获。

易错点:异步回调里不要漏掉 return;不要把 err 当字符串;同步读取会阻塞,推荐异步。

fs 写入文件:覆盖、追加与路径错误 ​

为什么需要:程序经常要生成或更新文件。
怎么想:fs.writeFile 默认覆盖原内容,文件不存在会自动创建;追加用 fs.appendFile。
怎么做:

js
const fs = require('fs')
const path = require('path')

const filename = path.join(__dirname, './data/b.txt')
const data = '你好,小乐儿\n'

fs.writeFile(filename, data, (err) => {
  if (err) {
    console.log('写入失败', err.errno, err.code)
    return
  }
  console.log('写入成功')
})

转写稿中写入失败的调试关键:用 __filename 拼路径会拼到当前 JS 文件后面,导致路径错误;应改用 __dirname,或用 path.resolve('./data/b.txt')。同步写入用 fs.writeFileSync,可配合 try/catch。追加写可用 fs.appendFile 或 fs.appendFileSync,循环追加可写多行。写入 Buffer 时会被编码,例如数字 100 可能显示为字符 d。

易错点:writeFile 是覆盖不是追加;路径拼错是常见失败原因;同步写入失败要用 try/catch。

文件重命名与删除:rename 也能移动位置 ​

为什么需要:文件管理需要改名、移动、删除。
怎么想:fs.rename(oldPath, newPath, callback) 可改文件名,也可改变完整路径,因此能移动文件。fs.unlink(path, callback) 删除文件。
怎么做:

js
fs.rename('./data/a.txt', './data/a.md', (err) => {
  if (err) return console.log('重命名失败')
  console.log('重命名成功')
})

fs.unlink('./data/a.md', (err) => {
  if (err) return console.log('删除失败')
  console.log('删除成功')
})

易错点:再次运行 rename 会因旧文件不存在而失败;删除不存在的文件也会失败。同步版本分别是 renameSync、unlinkSync。

课堂画面 ​

课堂画面 1

课堂画面 2

课堂画面 3

课堂画面 4

课堂画面 5

代码示例 ​

示例 1:path 内置模块——拼接与拆解路径 ​

js
// path-demo.js
// 第一步:引入内置模块,用变量接住 require 返回的对象
const path = require('path');

// 1) join:拼接路径
console.log(path.join('images', 'date'));                  // images\date(Windows)
console.log(path.join(__dirname, './data', 'images'));     // 绝对路径 + 后面的片段
console.log(path.join(__dirname, 'data', '..', 'images')); // .. 会往回退一步

// 2) isAbsolute:判断是不是绝对路径,返回 true / false
console.log(path.isAbsolute('./images/100.jpg'));          // false
console.log(path.isAbsolute(__filename));                  // true

// 3) 拆解路径中的各个部分
console.log(path.dirname(__filename));    // 目录部分(不带文件名)
console.log(path.basename(__filename));   // 文件名部分 path-demo.js
console.log(path.extname(__filename));    // 扩展名部分 .js

// 4) resolve:把相对路径解析成绝对路径(以当前脚本所在目录为基准)
console.log(path.resolve('./images/date')); // C:\...\images\date
console.log(path.join('./images', 'date')); // images\date —— 只是拼接

关键行与易错点

  • require('path') 的参数是模块名字符串,返回值是一个对象;不引入就不能用,变量名叫什么都行,习惯上叫 path。
  • __dirname 是当前脚本所在目录的绝对路径,__filename 是当前脚本的绝对路径,用它们拼路径才“稳”。
  • join 只是单纯拼接,它会按当前操作系统自动选分隔符:Windows 是反斜杠 `,Linux/macOS 是正斜杠 /。所以不要手写 `,否则代码挪到 Linux 服务器上就不认识了。
  • resolve 比 join 更进一步:它会把相对路径转成绝对路径,./、../ 都会基于脚本所在目录解析;join 不会转绝对路径。
  • dirname / basename / extname 分别是目录、文件名、扩展名,注意 basename 不含目录,extname 含那个点。

示例 2:fs 读取文件——异步(推荐)+ 同步(try/catch) ​

js
// fs-read.js
const fs = require('fs');
const path = require('path');

// 先把要读的文件准备好(真实项目里这个文件本来就存在)
fs.mkdirSync(path.join(__dirname, 'data'), { recursive: true });
fs.writeFileSync(path.join(__dirname, 'data', 'a.txt'), '锄禾日当午\n粒粒皆辛苦', 'utf-8');

// 用绝对路径读取:效率更高、准确性更高,程序挪位置也不怕
const fileName = path.join(__dirname, 'data', 'a.txt');

// ---------- 异步读取(推荐) ----------
fs.readFile(fileName, 'utf-8', (err, data) => {
  if (err) {
    console.log('文件读取失败');
    console.log(err.errno, err.code); // 错误编号 / 错误代码
    return;                           // 关键:不 return,后面的代码还会继续跑
  }
  console.log('读取到的内容:', data);
});

console.log('hello 高晓乐'); // 这行会先执行,因为读文件是异步的

// ---------- 同步读取(了解,会阻塞) ----------
try {
  const data = fs.readFileSync(fileName, 'utf-8');
  console.log('同步读取:', data);
} catch (err) {
  console.log('文件读取失败');
  console.log(err.errno, err.code);
}

关键行与易错点

  • readFile(路径, 编码, 回调) 三个参数,中间编码可省略;省略时 data 是 Buffer(一堆十六进制),要再调 data.toString() 才是字符串,所以直接写 'utf-8' 更省事。
  • 回调第一个参数 err 是错误对象:没出错时是 null,出错时才有值,可以取 err.errno(错误编号)和 err.code(错误代码)。
  • err 判断后一定记得 return,否则“读取失败”和“读取成功”会一起打印。
  • 同步方法都带 Sync 后缀,有返回值、没有回调,用 try...catch 兜异常;它会阻塞,转写稿里反复强调:能用异步就用异步。
  • 打印顺序是:hello 高晓乐 → 同步读取 → 读取到的内容,理解这个顺序就理解了“非阻塞”。

示例 3:fs 写入 / 追加 / 重命名 / 删除 ​

js
// fs-write.js
const fs = require('fs');
const path = require('path');

fs.mkdirSync(path.join(__dirname, 'data'), { recursive: true });
// 准备一个待重命名、待删除的文件
fs.writeFileSync(path.join(__dirname, 'data', 'a.txt'), '待重命名', 'utf-8');

// 写入地址用 resolve 转成绝对路径,别再用 __filename 拼
const fileName = path.resolve('./data/b.txt');
const data01 = '你好,小乐儿\n' + Math.random() + '\n';

// ---------- 异步写入:文件不存在会自动创建,存在则覆盖 ----------
fs.writeFile(fileName, data01, (err) => {
  if (err) {
    console.log('写入失败', err.errno, err.code);
    return;
  }
  console.log('写入成功');

  // 写入完成后再追加,避免两个异步操作抢同一个文件
  fs.appendFile(fileName, '追加的一行\n', (err2) => {
    if (err2) {
      console.log('追加失败', err2.errno, err2.code);
    } else {
      console.log('追加成功');
    }
  });
});

// ---------- 重命名(也能用来移动文件位置) ----------
fs.rename(
  path.join(__dirname, 'data', 'a.txt'),
  path.join(__dirname, 'data', 'a.md'),
  (err) => {
    console.log(err ? '重命名失败' : '重命名成功');
  }
);

// ---------- 删除文件 ----------
fs.unlink(path.join(__dirname, 'data', 'a.md'), (err) => {
  if (err) {
    console.log('文件删除失败', err.errno, err.code);
  } else {
    console.log('文件删除成功');
  }
});

关键行与易错点

  • writeFile 的回调只接收一个 err 参数(写入没有“读出来的数据”),这和 readFile 的两个参数不一样。
  • writeFile 是覆盖写:文件不存在就创建,已存在就把原内容清空重写;想追加要用 appendFile。
  • 拼路径最容易翻车:转写稿里就是因为用了 __filename(指向 .js 文件本身)去拼,结果写到了错误位置,应改用 __dirname 或 path.resolve()。
  • 从编程角度看,“重命名”和“移动位置”是一回事:rename 改的是完整路径,只改最后一段就是改名,换掉前面目录就是移动。
  • unlink 只能删文件,删完再运行一次必然失败(文件已不存在),所以错误分支一定要处理。
  • 同步版本对应 writeFileSync / appendFileSync / renameSync / unlinkSync,需要容错时同样用 try...catch 包起来。

常见错误 ​

  1. 现象:直接调用 path.join 或 fs.readFile 报未定义;原因:使用内置模块前未 require 引入;修法:先 const path = require('path') / const fs = require('fs'),再用变量调用。
  2. 现象:拼接出的文件路径多出或缺少目录,读写失败;原因:用 __filename 当目录拼接,或相对路径基准理解错误;修法:目录拼接用 __dirname,需要绝对路径时用 path.resolve。
  3. 现象:fs.readFile 读出的内容是 Buffer,直接当字符串处理出现乱码;原因:异步读取未指定编码;修法:在参数中指定 'utf8',或对 Buffer 调用 toString()。
  4. 现象:读取失败后仍继续执行后续成功逻辑;原因:回调中判断 err 后没有 return;修法:错误分支输出信息后立即 return,或把成功逻辑放到 else 中。
  5. 现象:异步读写代码的输出顺序与书写顺序不一致;原因:把异步回调当成同步代码理解;修法:依赖回调/后续流程处理结果,不要假设回调前的代码会等它完成。
  6. 现象:写入文件后原内容消失,或追加内容不符合预期;原因:误把 writeFile 当追加写,或误把 appendFile 当覆盖写;修法:覆盖用 writeFile,追加用 appendFile,并明确文件不存在时的创建行为。
  7. 现象:重命名/移动文件失败或删错文件;原因:rename 的旧路径、新路径不是完整目标路径,删除前未确认文件存在;修法:用绝对路径明确源和目标,删除前判断存在性并处理错误。

练习 ​

  1. 使用 path 模块拼接当前脚本目录下 data/a.txt 的绝对路径,并输出结果。
  2. 使用 fs 异步读取一个文本文件,指定 utf8 编码,并分别处理读取成功和失败。
  3. 分别用覆盖写和追加写向同一个文件写入内容,运行两次后观察并解释文件内容变化。
  4. 使用 fs.rename 将 data/a.txt 移动到当前脚本目录下,并处理源文件不存在的情况。
  5. 使用同步方式删除一个文件,并用 try/catch 处理删除失败。

原视频对照 ​

#视频时长
1内置模块path15:32
2读取文件39:46
3写入文件14:24
4文件重命名05:14
5文件删除02:10

小结 ​

  1. 内置模块使用前必须先引入,变量名可自定义,但后续调用要一致。
  2. 面对大量 API 不必全记,应先查文档,再挑常用方法解决实际问题。
  3. 路径拼接优先使用 path 模块,涉及文件读写时优先构造绝对路径。
  4. 文件读写要明确同步与异步的差异,实际开发中优先考虑异步方式。
  5. 异步操作必须认真处理错误对象,错误分支要及时终止后续成功逻辑。
  6. 写入文件要区分覆盖写与追加写,避免误用导致数据丢失或重复。
  7. 同步代码可用 try/catch 提升健壮性,但不能把它当成异步回调的替代。
  8. rename 不仅能改文件名,也能改变文件所在路径,本质是改变完整文件名。