node-fs模块

9 阅读9分钟

1、fs模块是什么

Node.js 中的 fs 模块(File System 模块)是用于与文件系统交互的核心模块,提供了读取、写入、删除、修改文件及目录等操作的 API,支持同步和异步两种调用方式。

2、如何导入fs模块

// 方式1:CommonJS 规范(Node.js 默认) 
const fs = require('fs'); 
// 方式2:ES 模块规范(需在 package.json 中设置 "type": "module") 
import fs from 'fs';

3、fs模块的常用方法


方法描述类型
fs.readFile(path, callback)读取文件内容异步
fs.readFileSync(path)读取文件内容同步
fs.writeFile(path, data, callback)写入内容到文件(覆盖原有内容)异步
fs.writeFileSync(path, data)写入内容到文件(覆盖原有内容)同步
fs.appendFile(path, data, callback)追加内容到文件异步
fs.appendFileSync(path, data)追加内容到文件同步
fs.unlink(path, callback)删除文件异步
fs.unlinkSync(path)删除文件同步
fs.mkdir(path, callback)创建目录异步
fs.mkdirSync(path)创建目录同步
fs.rmdir(path, callback)删除空目录异步
fs.rmdirSync(path)删除空目录同步
fs.readdir(path, callback)读取目录中的文件和子目录列表异步
fs.readdirSync(path)读取目录中的文件和子目录列表同步
fs.stat(path, callback)获取文件 / 目录的详细信息异步
fs.statSync(path)获取文件 / 目录的详细信息同步

3-1读取文件

  • 异步:fs.readFile(path[, encoding], callback)
    接收文件路径、编码格式(可选,默认 Buffer)和回调函数,回调参数为错误信息和文件内容。
  • 同步:fs.readFileSync(path[, encoding])
    直接返回文件内容,需用 try/catch 捕获错误。
// 异步
fs.readFile('file.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});

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

// 2-3 读取文件夹
fs.readdir('../文件夹 ', (err, data) => {
  if (err) {
    console.log('读取失败');
    return;
  }
  console.log(data);
});

流式读取

流式读取是 Node.js 中高效处理文件(尤其是大文件)的方式,它将文件内容分割成小块(chunk),逐块读取并处理,而非一次性将整个文件加载到内存。 核心特点:

  • 内存高效:无需一次性加载全部内容,适合 GB 级大文件,避免内存溢出
  • 实时处理:读取到部分数据即可立即处理,无需等待完整文件加载
  • 事件驱动:通过 data 事件获取数据块,end 事件标识读取完成
const fs = require('fs');
const readStream = fs.createReadStream('large-file.txt');

// 每收到一块数据(trunk)就触发
readStream.on('data', (chunk) => {
  console.log('收到数据块:', chunk.toString());
});

// 全部读取完成触发
readStream.on('end', () => {
  console.log('读取完毕');
});

// 发生错误时触发
readStream.on('error', (err) => {
  console.error('读取错误:', err);
});

文件读取的常见场景

  1. 配置加载:应用启动时读配置文件(如 JSON、YAML),获取端口、数据库连接等运行参数;
  2. 数据导入:从 CSV、Excel 或备份文件中读数据,用于分析、数据库恢复等;
  3. 内容交互:文本编辑器读文件展示内容、媒体播放器读文件加载音视频;
  4. 日志分析:读日志文件排查故障、分析系统运行 / 用户行为;
  5. 代码 / 脚本执行:解释器 / 编译器读源码文件,执行脚本或编译生成程序;
  6. 大数据处理:分块读海量数据文件,避免内存不足(如分布式计算场景)。

3-2写入文件

  • 异步:fs.writeFile(path, data[, options], callback)
    将 data 写入指定文件(覆盖原有内容),完成后执行回调。
  • 同步:fs.writeFileSync(path, data[, options])
    同步写入,同样覆盖原有内容,需处理可能的错误。
// 异步
fs.writeFile('file.txt', 'Hello World', (err) => {
  if (err) throw err;
  console.log('文件已写入');
});

// 同步
try {
  fs.writeFileSync('file.txt', 'Hello World');
  console.log('文件已写入');
} catch (err) {
  console.error(err);
}

流式写入

在 Node.js 中,流式写入(Stream Writing)是处理大文件或持续数据写入的高效方式,它可以分块处理数据,避免一次性加载大量数据到内存中。

关键方法和事件:

  • fs.createWriteStream(path[, options]):创建写入流
  • writeStream.write(chunk[, encoding][, callback]):写入数据块
  • writeStream.end([chunk][, encoding][, callback]):结束写入流
  • 'drain' 事件:当内部缓冲区被清空时触发,此时可以继续写入
  • 'finish' 事件:所有数据已被写入底层系统时触发
  • 'error' 事件:发生错误时触发
// 示例
const fs = require('fs');//导入 Node.js 内置的 `fs` 模块
let ws = fs.createWriteStream('./观书有感.txt'); 
//调用 `fs.createWriteStream()` 方法创建一个可写流(WriteStream),用于向指定文件写入数据。
//'./观书有感.txt'` 是目标文件路径(当前目录下的 `观书有感.txt`),如果文件不存在会自动创建。
//变量 `ws` 存储这个可写流对象,后续通过它进行写入操作。
ws.write('111\r\n'); 
ws.write('222\r\n');
ws.write('333\r\n'); 
ws.write('444\r\n');
ws.end();
//调用 `end()` 方法结束写入流,表明所有数据已写入完成。

文件写入的常见场景:

  • 日志记录:服务器、应用程序将操作、错误、访问等日志信息写入文件,用于后续分析和排查问题。
  • 数据持久化:把内存中的数据(如文档内容、应用配置等)长期保存到文件,以便后续读取和使用。
  • 数据导出:将应用程序或数据库中的数据,以特定格式(如 CSV、Excel、PDF 等)导出为文件,用于数据迁移或分享。
  • 动态内容生成:根据不同逻辑(如 Web 请求、模板渲染等)动态生成内容并写入文件,像静态网站生成、代码自动生成等场景。
  • 大数据处理:处理海量数据时,分块将数据或处理结果写入文件,避免内存不足,如大规模数据分析、数据清洗等场景。

3-3追加文件

  • 异步:fs.appendFile(path, data[, options], callback)
    在文件末尾添加内容(不覆盖原有内容),适合日志记录等场景。
  • 同步:fs.appendFileSync(path, data[, options])
    同步追加,功能与异步版本一致。
// 异步
fs.appendFile('file.txt', '追加内容', (err) => {
  if (err) throw err;
  console.log('内容已追加');
});

// 同步
try {
  fs.appendFileSync('file.txt', '追加内容');
  console.log('内容已追加');
} catch (err) {
  console.error(err);
}

//另外fs.writeFile也可以实现追加效果,只需要增加一个配置对象{flag:a}
//w = 写入模式,a = 追加模式,r = 读取模式
fs.writeFile('file.txt', '111', {flag:a},(err) => {
  if (err) throw err;
  console.log('写入成功');
});

3-4 删除文件

  • 异步:fs.unlink(path, callback)
    删除指定文件,删除成功后执行回调。
  • 同步:fs.unlinkSync(path)
    同步删除文件,无返回值,错误需通过 try/catch 处理。
// 异步
fs.unlink('file.txt', (err) => {
if (err) throw err;
console.log('文件已删除');
});

// 同步
try {
fs.unlinkSync('file.txt');
console.log('文件已删除');
} catch (err) {
console.error(err);
}
  • 异步:fs.rm(path, options, callback)
    删除指定文件或目录,删除成功后执行回调。支持通过 options 配置递归删除(recursive: true)等行为。
  • 同步:fs.rmSync(path, options)
    同步删除文件或目录,无返回值,错误需通过 try/catch 处理。可通过 options 配置递归删除等行为。
// 异步
fs.rm('./论语.txt', { recursive: true }, (err) => {
  if (err) {
    console.log('删除失败~');
    return;
  }
  console.log('删除成功');
});

// 同步
try {
  fs.rmSync('./论语.txt', { recursive: true });
  console.log('删除成功');
} catch (err) {
  console.error('删除失败~', err);
}

3-5 创建目录/文件夹

  • 异步:fs.mkdir(path[, options], callback)
    创建单层目录,若目录已存在会报错(可通过 options 设置递归创建)。
  • 同步:fs.mkdirSync(path[, options])
    同步创建目录,用法与异步版本对应。
// 异步
fs.mkdir('newdir', (err) => {
  if (err) throw err;
  console.log('目录已创建');
});

// 同步
try {
  fs.mkdirSync('newdir');
  console.log('目录已创建');
} catch (err) {
  console.error(err);
}

// 递归创建 (加上{ recursive: true })
fs.mkdir('./a/b/c', { recursive: true }, err => { 
    if (err) { console.log('创建失败~'); 
    return
    ; } console.log('创建成功'); }); 

{ recursive: true } 是 Node.js 文件操作中的一个配置选项:

  • 用于 fs.mkdir() 时:自动创建路径中所有不存在的目录(如创建 a/b/c 时,会自动创建 a 和 b

  • 用于 fs.rm() 时:递归删除目录及其所有子内容(包括非空目录)

简单说,就是「自动处理多层级结构」的意思。

3-6 读取目录

  • 异步:fs.readdir(path[, options], callback)
    获取目录下所有文件 / 子目录名称数组,通过回调返回。
  • 同步:fs.readdirSync(path[, options])
    同步返回目录内容列表。
// 异步
fs.readdir('dir', (err, files) => {
  if (err) throw err;
  console.log(files);
});

// 同步
try {
  const files = fs.readdirSync('dir');
  console.log(files);
} catch (err) {
  console.error(err);
}

3-7获取文件信息

  • 异步:fs.stat(path, callback)
    获取文件 / 目录的元数据(大小、类型、修改时间等),通过 stats 对象访问。
  • 同步:fs.statSync(path)
    同步返回 stats 对象,可用于判断是文件(isFile ())还是目录(isDirectory ())。
// 异步
fs.stat('file.txt', (err, stats) => {
  if (err) throw err;
  console.log(stats.size); // 文件大小
  console.log(stats.isFile()); // 是否为文件
});

// 同步
try {
  const stats = fs.statSync('file.txt');
  console.log(stats.mtime); // 最后修改时间
} catch (err) {
  console.error(err);
}

3-8文件重命名

在 Node.js 中,文件重命名主要通过 fs 模块的 rename() 或 renameSync() 方法实现,可实现文件 / 目录的重命名或移动功能。

  • 异步方式(推荐)
const fs = require('fs');
fs.rename('旧文件名.txt', '新文件名.txt', (err) => {
  if (err) throw err;
  console.log('重命名成功');
});
  • 同步方式
const fs = require('fs');
try {
  fs.renameSync('旧路径', '新路径');
  console.log('重命名成功');
} catch (err) {
  console.error(err);
}

3-9查看资源状态

在 Node.js 中,可通过fs模块的多个方法查看资源状态,以下是具体介绍:

1. fs.stat()fs.statSync()

  • 功能fs.stat()是异步方法,fs.statSync()是同步方法, 用于获取文件或目录的详细信息,像文件大小、创建时间、修改时间、访问时间、文件权限等。
  • 示例
const fs = require('fs');

// 异步方式
fs.stat('example.txt', (err, stats) => {
    if (err) {
        console.error('获取状态失败:', err);
        return;
    }
    console.log('文件大小:', stats.size);
    console.log('创建时间:', stats.birthtime);
    console.log('修改时间:', stats.mtime);
});

// 同步方式
try {
    const stats = fs.statSync('example.txt');
    console.log('文件大小:', stats.size);
    console.log('创建时间:', stats.birthtime);
    console.log('修改时间:', stats.mtime);
} catch (err) {
    console.error('获取状态失败:', err);
}

2. fs.lstat()fs.lstatSync()

  • 功能:和fs.stat()类似,区别在于,当目标是符号链接(软链接)时,fs.lstat()返回的是符号链接本身的状态,而不是符号链接所指向的文件或目录的状态。
  • 示例
const fs = require('fs');

// 异步方式
fs.lstat('symlink.txt', (err, stats) => {
    if (err) {
        console.error('获取符号链接状态失败:', err);
        return;
    }
    console.log('符号链接大小:', stats.size);
});

// 同步方式
try {
    const stats = fs.lstatSync('symlink.txt');
    console.log('符号链接大小:', stats.size);
} catch (err) {
    console.error('获取符号链接状态失败:', err);
}

3. fs.access()fs.accessSync()

  • 功能:检查当前用户对文件或目录是否具有特定的访问权限,比如读权限、写权限、执行权限等。
  • 示例
const fs = require('fs');
const { constants } = fs;

// 异步方式,检查是否有读和写权限
fs.access('test.txt', constants.R_OK | constants.W_OK, (err) => {
    if (err) {
        console.log('没有读或写权限');
        return;
    }
    console.log('具有读和写权限');
});

// 同步方式
try {
    fs.accessSync('test.txt', constants.R_OK | constants.W_OK);
    console.log('具有读和写权限');
} catch (err) {
    console.log('没有读或写权限');
}

4. fs.existsSync()

  • 功能:同步检查文件或目录是否存在,返回布尔值。不过不推荐在异步操作场景中大量使用,因为会阻塞事件循环,影响程序性能。
  • 示例
const fs = require('fs');
const exists = fs.existsSync('check.txt');
if (exists) {
    console.log('文件存在');
} else {
    console.log('文件不存在');
}