Node.js 中 fs 模块的高级用法
目录
1. 流式文件处理
示例:大文件复制
2. 文件监控
示例:使用 fs.watch 监控文件变化
3. 异步递归操作
示例:异步递归遍历目录
4. 文件权限管理
示例:修改文件权限
5. 原子操作
示例:原子重命名文件
在 Node.js 里,fs
(文件系统)模块提供了一系列用于与文件系统进行交互的方法。除了常见的读写文件操作,还有一些高级用法,以下为你详细介绍:
1. 流式文件处理
在处理大文件时,一次性将整个文件加载到内存中可能会导致内存溢出。使用流(Stream)可以逐块处理文件,减少内存使用。
示例:大文件复制
const fs = require('fs');
// 创建可读流
const readStream = fs.createReadStream('largeFile.txt');
// 创建可写流
const writeStream = fs.createWriteStream('copiedLargeFile.txt');
// 将可读流的数据管道传输到可写流
readStream.pipe(writeStream);
// 监听可读流的结束事件
readStream.on('end', () => {
console.log('文件复制完成');
});
// 监听错误事件
readStream.on('error', (err) => {
console.error('读取文件时出错:', err);
});
writeStream.on('error', (err) => {
console.error('写入文件时出错:', err);
});
在上述代码中,createReadStream
方法创建了一个可读流,createWriteStream
方法创建了一个可写流。通过 pipe
方法将可读流的数据传输到可写流,实现了大文件的复制。
2. 文件监控
fs.watch
和 fs.watchFile
方法可用于监控文件或目录的变化。
示例:使用 fs.watch
监控文件变化
const fs = require('fs');
// 监控文件
fs.watch('test.txt', (eventType, filename) => {
if (filename) {
console.log(`${filename} 文件发生了 ${eventType} 事件`);
}
});
fs.watch
方法会在文件或目录发生变化时触发回调函数,eventType
表示事件类型(如 change
或 rename
),filename
表示发生变化的文件或目录名。
3. 异步递归操作
在处理目录树时,可能需要递归地遍历目录和子目录。可以使用异步函数和递归实现这一功能。
示例:异步递归遍历目录
const fs = require('fs');
const path = require('path');
async function traverseDirectory(dir) {
try {
const files = await fs.promises.readdir(dir);
for (const file of files) {
const filePath = path.join(dir, file);
const stat = await fs.promises.stat(filePath);
if (stat.isDirectory()) {
// 如果是目录,递归调用
await traverseDirectory(filePath);
} else {
console.log(filePath);
}
}
} catch (err) {
console.error('遍历目录时出错:', err);
}
}
// 调用函数开始遍历
traverseDirectory('yourDirectoryPath');
在上述代码中,traverseDirectory
函数会递归地遍历指定目录及其子目录,并打印出所有文件的路径。
4. 文件权限管理
fs
模块可以用于修改文件的权限。
示例:修改文件权限
const fs = require('fs');
// 修改文件权限为 755
fs.chmod('test.txt', 0o755, (err) => {
if (err) {
console.error('修改文件权限时出错:', err);
} else {
console.log('文件权限修改成功');
}
});
fs.chmod
方法用于修改文件的权限,第一个参数是文件路径,第二个参数是权限模式(使用八进制表示),第三个参数是回调函数。
5. 原子操作
在多进程或多线程环境中,可能需要进行原子操作以避免数据竞争。fs
模块提供了一些原子操作方法,如 fs.rename
。
示例:原子重命名文件
const fs = require('fs');
fs.rename('oldName.txt', 'newName.txt', (err) => {
if (err) {
console.error('重命名文件时出错:', err);
} else {
console.log('文件重命名成功');
}
});
fs.rename
方法可以原子地重命名文件,确保操作的原子性。