阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > fs模块的核心API

fs模块的核心API

作者:陈川 阅读数:29932人阅读 分类: Node.js

fs模块的核心API

Node.js的fs模块提供了文件系统操作的核心功能,允许开发者与文件系统进行交互。该模块包含同步和异步两种形式的API,支持文件读写、目录操作、权限管理等多种功能。fs模块是Node.js中最基础且使用频率最高的模块之一。

文件读写操作

异步文件读取

fs.readFile()是最常用的异步读取文件方法,它接收文件路径、编码格式和回调函数作为参数:

const fs = require('fs');

fs.readFile('example.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});

同步文件读取

同步版本fs.readFileSync()会阻塞事件循环直到文件读取完成:

try {
  const data = fs.readFileSync('example.txt', 'utf8');
  console.log(data);
} catch (err) {
  console.error(err);
}

流式文件读取

对于大文件,建议使用流式读取:

const readStream = fs.createReadStream('largefile.txt', 'utf8');
readStream.on('data', (chunk) => {
  console.log('Received chunk:', chunk.length);
});

文件写入操作

异步文件写入

fs.writeFile()用于异步写入文件:

fs.writeFile('output.txt', 'Hello Node.js', 'utf8', (err) => {
  if (err) throw err;
  console.log('File written successfully');
});

追加写入

fs.appendFile()在文件末尾追加内容:

fs.appendFile('log.txt', `${new Date()}: New log entry\n`, (err) => {
  if (err) console.error(err);
});

流式写入

大文件写入应使用可写流:

const writeStream = fs.createWriteStream('bigfile.txt');
for (let i = 0; i < 10000; i++) {
  writeStream.write(`Line ${i}\n`);
}
writeStream.end();

文件系统操作

检查文件存在

fs.existsSync()同步检查文件是否存在:

if (fs.existsSync('config.json')) {
  console.log('Config file exists');
}

获取文件状态

fs.stat()获取文件元数据:

fs.stat('package.json', (err, stats) => {
  if (err) throw err;
  console.log(`Size: ${stats.size} bytes`);
  console.log(`Is file: ${stats.isFile()}`);
});

重命名文件

fs.rename()修改文件名或移动文件:

fs.rename('oldname.txt', 'newname.txt', (err) => {
  if (err) throw err;
});

目录操作

创建目录

fs.mkdir()创建新目录:

fs.mkdir('new-directory', { recursive: true }, (err) => {
  if (err) throw err;
});

读取目录内容

fs.readdir()列出目录中的文件和子目录:

fs.readdir('./', (err, files) => {
  if (err) throw err;
  files.forEach(file => console.log(file));
});

删除目录

fs.rmdir()删除空目录,fs.rm()可递归删除:

fs.rm('empty-dir', { recursive: true }, (err) => {
  if (err) console.error(err);
});

文件监视

监视文件变化

fs.watch()监视文件或目录的变化:

const watcher = fs.watch('config.json', (eventType, filename) => {
  console.log(`Event type: ${eventType}, File: ${filename}`);
});

// 停止监视
setTimeout(() => watcher.close(), 10000);

高级文件操作

文件描述符操作

使用文件描述符进行底层操作:

fs.open('data.bin', 'r+', (err, fd) => {
  if (err) throw err;
  
  const buffer = Buffer.alloc(1024);
  fs.read(fd, buffer, 0, buffer.length, 0, (err, bytes) => {
    if (err) throw err;
    console.log(buffer.slice(0, bytes).toString());
    fs.close(fd, (err) => { if (err) throw err; });
  });
});

文件权限修改

fs.chmod()修改文件权限:

fs.chmod('script.sh', 0o755, (err) => {
  if (err) throw err;
});

性能优化技巧

批量操作使用Promise

将回调风格的API转换为Promise:

const { promisify } = require('util');
const readFileAsync = promisify(fs.readFile);

async function processFiles() {
  try {
    const data = await readFileAsync('data.json');
    console.log(JSON.parse(data));
  } catch (err) {
    console.error(err);
  }
}

使用fs-extra模块

fs-extra提供了更多便利方法:

const fse = require('fs-extra');

// 复制整个目录
fse.copy('/path/to/source', '/path/to/dest')
  .then(() => console.log('Copy complete'))
  .catch(err => console.error(err));

错误处理最佳实践

正确处理ENOENT错误

文件不存在时的错误处理:

fs.readFile('missing.txt', (err, data) => {
  if (err) {
    if (err.code === 'ENOENT') {
      console.log('File not found');
    } else {
      throw err;
    }
  }
});

资源清理

确保文件描述符被正确关闭:

let fd;
try {
  fd = fs.openSync('temp.txt', 'w');
  // 文件操作...
} finally {
  if (fd !== undefined) fs.closeSync(fd);
}

实际应用场景

配置文件读取

async function loadConfig() {
  try {
    const config = await fs.promises.readFile('config.json', 'utf8');
    return JSON.parse(config);
  } catch (err) {
    if (err.code === 'ENOENT') {
      return {}; // 返回默认配置
    }
    throw err;
  }
}

日志记录系统

class Logger {
  constructor(logFile) {
    this.logFile = logFile;
    this.stream = fs.createWriteStream(logFile, { flags: 'a' });
  }

  log(message) {
    const entry = `[${new Date().toISOString()}] ${message}\n`;
    this.stream.write(entry);
  }
}

与路径模块结合使用

路径解析与文件操作

const path = require('path');

function findConfigFile(dir) {
  const configPath = path.join(dir, 'config.json');
  if (fs.existsSync(configPath)) {
    return configPath;
  }
  const parentDir = path.dirname(dir);
  if (parentDir !== dir) {
    return findConfigFile(parentDir);
  }
  return null;
}

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌