Node.js fs 模块
fs (File System) 模块是 Node.js 内置的核心模块,用于与文件系统进行交互。
fs模块提供了一系列方法来处理文件的读取、写入、删除等操作。
fs 模块是 Node.js 开发中最常用的模块之一,特别是在需要处理本地文件的场景中。
如何使用 fs 模块?
要使用 fs 模块,首先需要导入它:
const fs = require('fs');
从 Node.js 14 开始,你也可以使用 ES6 的 import 语法:
实例
const fs = require('fs'); // CommonJS 方式
// 或
import fs from 'fs'; // ES Module 方式
// 或
import fs from 'fs'; // ES Module 方式
fs 模块的主要方法
1. 文件读取
同步读取文件 (readFileSync)
实例
const data = fs.readFileSync('example.txt', 'utf8');
console.log(data);
console.log(data);
'example.txt'
:要读取的文件路径'utf8'
:指定编码格式(可选)- 同步方法会阻塞代码执行,直到文件读取完成
异步读取文件 (readFile)
实例
fs.readFile('example.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
if (err) throw err;
console.log(data);
});
- 异步方法不会阻塞代码执行
- 通过回调函数处理结果
- 错误优先回调(err-first callback)是 Node.js 的常见模式
2. 文件写入
同步写入文件 (writeFileSync)
实例
fs.writeFileSync('output.txt', 'Hello, Node.js!');
异步写入文件 (writeFile)
实例
fs.writeFile('output.txt', 'Hello, Node.js!', (err) => {
if (err) throw err;
console.log('文件已保存');
});
if (err) throw err;
console.log('文件已保存');
});
3. 文件追加
同步追加 (appendFileSync)
实例
fs.appendFileSync('log.txt', '新的日志内容\n');
异步追加 (appendFile)
实例
fs.appendFile('log.txt', '新的日志内容\n', (err) => {
if (err) throw err;
});
if (err) throw err;
});
4. 文件状态检查 (stat)
实例
fs.stat('example.txt', (err, stats) => {
if (err) throw err;
console.log(`文件大小: ${stats.size} bytes`);
console.log(`创建时间: ${stats.birthtime}`);
console.log(`是否是文件: ${stats.isFile()}`);
console.log(`是否是目录: ${stats.isDirectory()}`);
});
if (err) throw err;
console.log(`文件大小: ${stats.size} bytes`);
console.log(`创建时间: ${stats.birthtime}`);
console.log(`是否是文件: ${stats.isFile()}`);
console.log(`是否是目录: ${stats.isDirectory()}`);
});
5. 文件删除
同步删除 (unlinkSync)
实例
fs.unlinkSync('fileToDelete.txt');
异步删除 (unlink)
实例
fs.unlink('fileToDelete.txt', (err) => {
if (err) throw err;
console.log('文件已删除');
});
if (err) throw err;
console.log('文件已删除');
});
Promise 和 async/await 支持
Node.js 10+ 提供了 fs/promises 模块,支持 Promise 风格的 API:
实例
const fs = require('fs').promises;
async function readFile() {
try {
const data = await fs.readFile('example.txt', 'utf8');
console.log(data);
} catch (err) {
console.error('读取文件出错:', err);
}
}
readFile();
async function readFile() {
try {
const data = await fs.readFile('example.txt', 'utf8');
console.log(data);
} catch (err) {
console.error('读取文件出错:', err);
}
}
readFile();
流式文件操作
对于大文件,使用流(Stream)可以提高性能:
读取流
实例
const readStream = fs.createReadStream('largeFile.txt', 'utf8');
readStream.on('data', (chunk) => {
console.log('接收到数据:', chunk.length);
});
readStream.on('end', () => {
console.log('读取完成');
});
readStream.on('error', (err) => {
console.error('读取错误:', err);
});
readStream.on('data', (chunk) => {
console.log('接收到数据:', chunk.length);
});
readStream.on('end', () => {
console.log('读取完成');
});
readStream.on('error', (err) => {
console.error('读取错误:', err);
});
写入流
实例
const writeStream = fs.createWriteStream('output.txt');
writeStream.write('第一行数据\n');
writeStream.write('第二行数据\n');
writeStream.end('最后一行数据');
writeStream.on('finish', () => {
console.log('写入完成');
});
writeStream.on('error', (err) => {
console.error('写入错误:', err);
});
writeStream.write('第一行数据\n');
writeStream.write('第二行数据\n');
writeStream.end('最后一行数据');
writeStream.on('finish', () => {
console.log('写入完成');
});
writeStream.on('error', (err) => {
console.error('写入错误:', err);
});
目录操作
创建目录
实例
fs.mkdir('newFolder', (err) => {
if (err) throw err;
console.log('目录已创建');
});
if (err) throw err;
console.log('目录已创建');
});
读取目录内容
实例
fs.readdir('./', (err, files) => {
if (err) throw err;
console.log('当前目录内容:', files);
});
if (err) throw err;
console.log('当前目录内容:', files);
});
删除目录
实例
fs.rmdir('emptyFolder', (err) => {
if (err) throw err;
console.log('目录已删除');
});
if (err) throw err;
console.log('目录已删除');
});
最佳实践
- 优先使用异步方法:避免阻塞事件循环
- 错误处理:始终处理可能的错误
- 使用流处理大文件:提高性能
- 路径处理:使用 path 模块处理跨平台路径问题
- 权限检查:操作前检查文件/目录权限
实际应用示例
文件复制功能
实例
const fs = require('fs');
function copyFile(source, target, cb) {
const readStream = fs.createReadStream(source);
const writeStream = fs.createWriteStream(target);
readStream.on('error', cb);
writeStream.on('error', cb);
readStream.on('close', () => {
writeStream.end();
cb(null);
});
readStream.pipe(writeStream);
}
copyFile('source.txt', 'target.txt', (err) => {
if (err) return console.error('复制失败:', err);
console.log('文件复制成功');
});
function copyFile(source, target, cb) {
const readStream = fs.createReadStream(source);
const writeStream = fs.createWriteStream(target);
readStream.on('error', cb);
writeStream.on('error', cb);
readStream.on('close', () => {
writeStream.end();
cb(null);
});
readStream.pipe(writeStream);
}
copyFile('source.txt', 'target.txt', (err) => {
if (err) return console.error('复制失败:', err);
console.log('文件复制成功');
});
点我分享笔记