Node.js 中 fs 模块的高级用法

fs 模块不仅提供了基本的文件读写操作,还支持一些高级功能,如流式读写、文件监视、Promise API 等。这些高级用法可以更好地满足复杂场景的需求,如大文件处理、实时监控等。


1. 流式读写

流(Stream)是 Node.js 中处理大文件或连续数据的核心概念。fs 模块提供了 fs.createReadStreamfs.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.watchfs.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:事件类型(如 changerename)。
  • 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 定期检查文件状态。
  • currprev:当前和之前的文件状态对象。
  • 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 模块的高级用法,可以更好地应对复杂的文件操作场景,提升代码的性能和可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小灰灰学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值