fs 模块不但提供了根本的文件读写操作,还支持一些高级功能,如流式读写、文件监督、Promise API 等。这些高级用法可以更好地满足复杂场景的需求,如大文件处理、实时监控等。
1. 流式读写
流(Stream)是 Node.js 中处理大文件或一连数据的核心概念。fs 模块提供了 fs.createReadStream 和 fs.createWriteStream 方法,用于以流的方式读写文件。
1.1 流式读取文件
- const fs = require('fs');
- // 创建可读流
- const readStream = fs.createReadStream('largeFile.txt', 'utf8');
- // 监听数据事件
- readStream.on('data', (chunk) => {
- console.log('Received chunk:', chunk.length);
- });
- // 监听结束事件
- readStream.on('end', () => {
- console.log('File reading completed');
- });
- // 监听错误事件
- readStream.on('error', (err) => {
- console.error('Error reading file:', err);
- });
复制代码 阐明:
- fs.createReadStream 创建一个可读流,逐块读取文件内容。
- data 事件:每次读取到数据块时触发。
- end 事件:文件读取完成时触发。
- error 事件:读取过程中发生错误时触发。
1.2 流式写入文件
- const fs = require('fs');
- // 创建可写流
- const writeStream = fs.createWriteStream('output.txt');
- // 写入数据
- writeStream.write('Hello, world!\n');
- writeStream.write('This is a stream example.\n');
- // 结束写入
- writeStream.end();
- // 监听完成事件
- writeStream.on('finish', () => {
- console.log('File writing completed');
- });
- // 监听错误事件
- writeStream.on('error', (err) => {
- console.error('Error writing file:', err);
- });
复制代码 阐明:
- fs.createWriteStream 创建一个可写流,逐块写入文件内容。
- write 方法:写入数据。
- end 方法:结束写入。
- finish 事件:写入完成时触发。
- error 事件:写入过程中发生错误时触发。
1.3 管道操作
管道(Pipe)是将可读流和可写流连接起来的便捷方式,常用于文件复制。
- const fs = require('fs');
- // 创建可读流和可写流
- const readStream = fs.createReadStream('source.txt');
- const writeStream = fs.createWriteStream('destination.txt');
- // 使用管道复制文件
- readStream.pipe(writeStream);
- // 监听完成事件
- writeStream.on('finish', () => {
- console.log('File copied successfully');
- });
- // 监听错误事件
- readStream.on('error', (err) => {
- console.error('Error reading file:', err);
- });
- writeStream.on('error', (err) => {
- console.error('Error writing file:', err);
- });
复制代码 2. 文件监督
fs 模块提供了 fs.watch 和 fs.watchFile 方法,用于监督文件或目次的变化。
2.1 利用 fs.watch
- const fs = require('fs');
- // 监视文件变化
- const watcher = fs.watch('example.txt', (eventType, filename) => {
- console.log(`Event type: ${eventType}`);
- if (filename) {
- console.log(`File changed: ${filename}`);
- }
- });
- // 关闭监视器
- setTimeout(() => {
- watcher.close();
- console.log('Watcher closed');
- }, 10000); // 10 秒后关闭
复制代码 阐明:
- fs.watch 监督文件或目次的变化。
- eventType:事件范例(如 change、rename)。
- filename:发生变化的文件名。
2.2 利用 fs.watchFile
- const fs = require('fs');
- // 监视文件变化
- fs.watchFile('example.txt', { interval: 1000 }, (curr, prev) => {
- if (curr.mtime !== prev.mtime) {
- console.log('File modified');
- }
- });
- // 停止监视
- setTimeout(() => {
- fs.unwatchFile('example.txt');
- console.log('Stopped watching file');
- }, 10000); // 10 秒后停止
复制代码 阐明:
- fs.watchFile 定期检查文件状态。
- curr 和 prev:当前和之前的文件状态对象。
- interval:检查隔断(毫秒)。
3. Promise API
Node.js 从 v10 开始提供了 fs.promises API,支持基于 Promise 的文件操作。
3.1 利用 fs.promises 读取文件
- const fs = require('fs').promises;
- async function readFile() {
- try {
- const data = await fs.readFile('example.txt', 'utf8');
- console.log('File content:', data);
- } catch (err) {
- console.error('Failed to read file:', err);
- }
- }
- readFile();
复制代码 3.2 利用 fs.promises 写入文件
- const fs = require('fs').promises;
- async function writeFile() {
- try {
- await fs.writeFile('example.txt', 'Hello, world!', 'utf8');
- console.log('File written successfully');
- } catch (err) {
- console.error('Failed to write file:', err);
- }
- }
- writeFile();
复制代码 4. 递归目次操作
4.1 递归读取目次
- const fs = require('fs');
- const path = require('path');
- async function readDirRecursive(dir) {
- const files = await fs.promises.readdir(dir);
- for (const file of files) {
- const filePath = path.join(dir, file);
- const stats = await fs.promises.stat(filePath);
- if (stats.isDirectory()) {
- await readDirRecursive(filePath); // 递归读取子目录
- } else {
- console.log('File:', filePath);
- }
- }
- }
- readDirRecursive('./').catch((err) => {
- console.error('Failed to read directory:', err);
- });
复制代码 4.2 递归删除目次
- const fs = require('fs');
- const path = require('path');
- async function deleteDirRecursive(dir) {
- const files = await fs.promises.readdir(dir);
- for (const file of files) {
- const filePath = path.join(dir, file);
- const stats = await fs.promises.stat(filePath);
- if (stats.isDirectory()) {
- await deleteDirRecursive(filePath); // 递归删除子目录
- } else {
- await fs.promises.unlink(filePath); // 删除文件
- console.log('Deleted file:', filePath);
- }
- }
- await fs.promises.rmdir(dir); // 删除空目录
- console.log('Deleted directory:', dir);
- }
- deleteDirRecursive('./temp').catch((err) => {
- console.error('Failed to delete directory:', err);
- });
复制代码 5. 总结
- 流式读写:得当处理大文件,制止内存占用过高。
- 文件监督:实时监控文件或目次的变化。
- Promise API:简化异步操作,制止回调地狱。
- 递归操作:处理嵌套目次结构。
通过把握 fs 模块的高级用法,可以更好地应对复杂的文件操作场景,提升代码的性能和可维护性。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |