发布于2026-07-16 阅读(0)
扫一扫,手机访问
Linux 下 Node.js 文件系统操作指南

在 Linux 环境下用 Node.js 操作文件系统,是服务器端开发绕不开的基本功。无论是处理日志、管理配置文件,还是搭建静态文件服务,都离不开对文件的读写、复制和删除。这里先说说核心思路和常见的坑。
Node.js 的文件系统操作,核心就是内置的 fs 模块。光有它还不够,通常还得配合 path 模块来处理跨平台路径,以及 os 模块来获取系统相关的常量(比如换行符)。这三个组合在一起,基本能覆盖大部分需求。
关于调用风格,Node.js 给了三种选择:
fs.readFile(path, 'utf8', callback) —— 最经典,但回调嵌套深了容易“回调地狱”。fs.promises.readFile(path, 'utf8') —— 推荐,配合 async/await 写起来很清爽。fs.readFileSync(path, 'utf8') —— 会阻塞事件循环,适合脚本初始化或启动阶段。常用的 API 其实就那些,列出来一目了然:
fs.readFile / readFileSyncfs.writeFile / writeFileSync(默认是覆盖写入)fs.appendFile / appendFileSyncfs.copyFilefs.mkdir / readdir / rmdirfs.unlink(删除文件)、fs.rm / fs.rmdir(删除目录,支持递归)fs.renamefs.stat / statSync一个小提示:Linux 下路径分隔符是 /,如果想让代码在 Windows 上也跑得通,记得用 path.join 来拼接路径。换行符方面,直接用 os.EOL 就能适配不同系统,省心。
直接上代码,这些都是实际开发中经常用到的组合。
// 1) 读取
const fs = require('fs').promises;
const path = require('path');
const os = require('os');
const file = path.join(__dirname, 'data.txt');
const content = await fs.readFile(file, 'utf8');
console.log(content);
// 2) 写入(覆盖)与追加
await fs.writeFile(file, '第一行\n', { mode: 0o644 }); // 设置文件权限为 0644
await fs.appendFile(file, `追加行 ${os.EOL}`, 'utf8');
// 3) 复制
await fs.copyFile(file, path.join(__dirname, 'data.bak.txt'));
// 4) 目录:创建多级、遍历
await fs.mkdir(path.join(__dirname, 'logs'), { recursive: true });
const files = await fs.readdir(__dirname);
console.log(files);
// 5) 重命名/移动
await fs.rename(
path.join(__dirname, 'data.bak.txt'),
path.join(__dirname, 'archive', 'data.txt')
);
// 6) 删除:文件与目录(递归删除)
await fs.unlink(path.join(__dirname, 'archive', 'data.txt'));
await fs.rm('logs', { recursive: true, force: true }); // 递归删除目录
// 7) 状态与类型判断
const st = await fs.stat(file);
console.log(st.isFile(), st.isDirectory());
几点说明:
writeFile 默认是覆盖写入,如果只想追加内容,记得用 appendFile。fs.rm(..., { recursive: true }) 可以递归删除目录,算是比较现代的做法。如果遇到旧版 Node.js,可能需要用 fs.rmdir 配合手动遍历,或者借助第三方库。mode: 0o644 是 Linux 下常见的文件权限设置,直接写在写入操作里就能生效。处理大文件时,最忌讳的就是一口气把整个文件读进内存。这时候就要请出流(Stream)了。
下面是一个用流来复制大文件的示例,通过管道(pipe)高效传输数据:
const fs = require('fs');
const read = fs.createReadStream('big.log', 'utf8');
const write = fs.createWriteStream('big.log.bak');
read.on('error', err => console.error('read error', err));
write.on('error', err => console.error('write error', err));
write.on('finish', () => console.log('copy done'));
read.pipe(write);
如果需要对大文件做逐行处理(比如分析日志),可以用 readline 模块配合流:
const fs = require('fs');
const readline = require('readline');
const rl = readline.createInterface({
input: fs.createReadStream('big.log', 'utf8'),
crlfDelay: Infinity
});
for await (const line of rl) {
// 处理每一行
console.log(line);
}
流和逐行读取的核心优势,就是在处理大文件时内存占用低、稳定性高。想想看,如果是几个G的日志文件,用 readFile 去读,机器不直接崩了才怪。
Linux 的权限模型是它的传统强项,但也容易踩坑。设置文件权限可以用 fs.writeFile 的 mode 参数(比如 0o755、0o644),或者直接用 fs.chmod / chmodSync 单独修改。一个基本原则:不要给敏感文件设置 0777 这种过于宽泛的权限,这点在 Linux 上尤其值得注意。
路径和换行符是跨平台开发的老生常谈。Linux 路径分隔符是 /,而 Windows 是 \,用 path.join 或 path.resolve 就能自动适应。换行符方面,Linux 是 \n,Windows 是 \r\n,直接用 os.EOL 即可统一处理。
编码方面,如果没指定 encoding,fs.readFile 默认返回的是 Buffer,常用的文本编码是 utf8。如果需要处理 GBK 这类非 UTF-8 编码的文件,可以借助 iconv-lite 等库进行转码,自己去写解码逻辑就太折腾了。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8