Node.js-fs模块

发布于:2025-06-26 ⋅ 阅读:(21) ⋅ 点赞:(0)
文件写入
  • 异步写入文件(fs.writeFile())

//语法:fs.writeFile(file, data[, options], callback)
//参数:文件路径、数据、选项(可选)、回调函数(err)

const fs = require('fs');

fs.writeFile('file.txt', 'Hello Node.js', function (err) {
  if (err) throw err;
  console.log('写入成功!');

})
  • 同步写入文件(fs.writeFileSync())
//阻塞主线程直至写入完成
//语法:fs.writeFileSync(file, data[, options])
//参数:文件路径、数据、选项(可选)

const fs = require('fs');

fs.writeFileSync('file.txt', 'Hello Node.js');
console.log('写入成功!');

Node.js 中的磁盘操作是由其他 线程 完成的,结果的处理有两种模式:

  • 同步处理 JavaScript 主线程 会等待 其他线程的执行结果,然后再继续执行主线程的代码,
    效率较低

  • 异步处理 JavaScript 主线程 不会等待 其他线程的执行结果,直接执行后续的主线程代码,
    效率较好

  • ​​追加写入 (appendFile)​

//语法:fs.appendFile(file, data[, options], callback)
//参数:文件路径、数据、选项(可选)、回调函数(err)

const fs = require('fs');

fs.appendFile('file.txt', '\nHello Node.js', function (err) {
    if (err) throw err;
    console.log('追加写入成功!');
  })
  
  • ​​追加写入 (appendFileSync)​
//语法:fs.appendFileSync(file, data[, options])
//参数:文件路径、数据、选项(可选)

const fs = require('fs');

fs.appendFileSync('file.txt', '\nHello Node.js');
console.log('追加写入成功!');
  • 流式写入文件(writeStream)
// 分块写入大文件,减少内存占用:
//语法:fs.createWriteStream(path[, options])
//参数:文件路径、选项(可选)

const fs = require('fs');

const ws = fs.createWriteStream('file.txt');
ws.write('Hello Node.js');
ws.end();
文件读取
  • 异步读取文件(fs.readFile())
// 非阻塞读取文件内容:
//语法:fs.readFile(path[, options], callback)
//参数:文件路径、选项(可选)、回调函数(err, data)

const fs = require('fs');

fs.readFile('file.txt', function (err, data) {
  if (err) throw err;
  console.log(data.toString());
})

fs.readFile('file.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});
  • 同步读取 (fs.readFileSync())​
// 阻塞读取文件内容:
//语法:fs.readFileSync(path[, options])
//参数:文件路径、选项(可选)
const fs = require('fs');
const data = fs.readFileSync('file.txt', 'utf8');
console.log(data);
  • ​​流式读取 (createReadStream)​
  //逐块读取大文件:
  //语法:fs.createReadStream(path[, options])
    const rs = fs.createReadStream('file.txt', 'utf8');
    rs.on('data', (chunk) => {
    console.log('数据块:', chunk);
    });
    rs.on('end', () => console.log('读取完成'));
  
文件移动与重命名​

在 Node.js 中,我们可以使用 rename 或 renameSync 来移动或重命名 文件或文件夹

// 语法:fs.rename(oldPath, newPath, callback)
//参数:旧路径、新路径、回调函数(err)
const fs = require('fs');

// 重命名
fs.rename('file.txt', 'newFile.txt', (err) => {
  if (err) throw err;
  console.log('文件重命名成功');
});

// 移动文件到新目录
// 目标目录必须存在,否则报错
fs.rename('newFile.txt', 'newdir/newFile.txt', (err) => {
  if (err) throw err;
});
文件删除​

在 Node.js 中,我们可以使用 unlink 或 unlinkSync 来删除 文件或文件夹

// 语法:fs.unlink(path, callback)
//参数:文件路径、回调函数(err)
const fs = require('fs');

// 删除文件
fs.unlink('file.txt', (err) => {
  if (err) throw err;
  console.log('文件删除成功');  
})
// 语法:fs.unlinkSync(path)
fs.unlinkSync('./file.txt');

// Node.js ≥14.4 (推荐)
fs.rm('file.txt', { recursive: true }, err => {});
文件夹操作
  • 创建文件夹 (mkdir)​
// fs.mkdir(path[, options], callback)
// fs.mkdirSync(path[, options])
// path 文件夹路径,options 选项配置( 可选 ),callback 操作后的回调

// 如果文件夹不存在,则创建文件夹,否则报错
const fs = require('fs');
fs.mkdir('newdir', (err) => {
  if (err) throw err;
  console.log('文件夹创建成功');
});

// 递归创建多层目录
fs.mkdir('dir1/dir2', { recursive: true }, (err) => {});

//递归同步创建文件夹
fs.mkdirSync('x/y/z', {recursive: true});
  • ​​读取文件夹内容 (readdir)​
  • 在 Node.js 中,我们可以使用 readdir 或 readdirSync 来读取文件夹

fs.readdir(path[, options], callback)
fs.readdirSync(path[, options])
// path 文件夹路径 // options 选项配置( 可选 )callback 操作后的回调

//异步读取
fs.readdir('./newdir', (err, data) => {
if(err) throw err;
console.log(data);
});
//同步读取
let data = fs.readdirSync('./newdir');
console.log(data);
  • 删除文件夹( rmdir )
    在 Node.js 中,我们可以使用 rmdir 或 rmdirSync 来删除文件夹
fs.rmdir(path[, options], callback)
fs.rmdirSync(path[, options])
 //path 文件夹路径 options 选项配置( 可选 ) callback 操作后的回调

 // 删除空文件夹
fs.rmdir('emptydir', (err) => {});

//同步递归删除文件夹
fs.rmdirSync('newdir', {recursive: true})


// 递归删除非空文件夹 (推荐)
fs.rm('./dir1/dir1', { recursive: true }, (err) => {});
fs.rm('mydir', { recursive: true }, (err) => {});
  • 查看资源状态
    在 Node.js 中,我们可以使用 stat 或 statSync 来查看资源的详细信息
fs.stat(path[, options], callback)
fs.statSync(path[, options])
// path 资源路径 // options 选项配置( 可选 ) callback 操作后的回调
// 异步
// size文件体积
// birthtime 创建时间
// mtime最后修改时间
// isFile 检测是否为文件
// isDirectory 检测是否为文件夹
fs.stat('file.txt', (err, stats) => {
if(err) throw err;
  console.log(stats.isFile());     // true
  console.log(stats.size);         // 文件大小(字节)
  console.log(stats.mtime);        // 修改时间
})
相对路径问题

fs 模块对资源进行操作时,路径的写法有两种:

  • 相对路径
    • /file.txt 当前目录下的file.txt
    • file.txt 等效于上面的写法
    • ./file.txt 当前目录的上一级目录中的file.txt
  • 绝对路径
    • D:/Program Files windows 系统下的绝对路径
    • usr/bin Linux 系统下的绝对路径

相对路径中所谓的 当前目录 ,指的是 命令行的工作目录 ,而并非是文件的所在目录
所以当命令行的工作目录与文件所在目录不一致时,会出现一些 BUG

__dirname

__dirname 与 require 类似,都是 Node.js 环境中的’全局’变量
__dirname 保存着 当前文件所在目录的绝对路径 ,可以使用 __dirname 与文件名拼接成绝对路径

使用 fs 模块的时候,尽量使用 __dirname 将路径转化为绝对路径,这样可以避免相对路径产生的
Bug

文件复制方法

fs.copyFile() 是Node.js 文件系统模块提供的异步文件复制方法,用于高效地将源文件复制到目标路径。

const fs = require('fs');
fs.copyFile(src, dest[, flags], callback);
//阻塞线程直至操作完成
fs.copyFileSync()
// src:源文件路径(字符串、Buffer 或 URL)。
// dest:目标文件路径(复制后文件的新位置)。
// flags:​​可选​​,指定复制行为的标志(默认为 0,即覆盖目标文件)。
//  COPYFILE_EXCL :目标文件存在时失败
// COPYFILE_FICLONE:尝试创建“写时复制”链接
// COPYFILE_FICLONE_FORCE:强制使用“写时复制” 
// callback:回调函数,接收一个 err 参数,处理复制结果。

fs.copyFile('source.txt', 'target.txt', fs.constants.COPYFILE_EXCL, (err) => {
  if (err) throw err;
  console.log('复制成功(目标文件不存在时才执行)');
});

fs.copyFile('source.jpg', 'backup.jpg', (err) => {
  if (err) console.error('复制失败:', err);
  else console.log('备份完成!');
});

try {
  fs.copyFileSync('source.txt', 'target.txt', fs.constants.COPYFILE_EXCL);
} catch (err) {
  if (err.code === 'EEXIST') console.log('文件已存在');
}
流式文件复制

在 Node.js 中,rs.pipe(ws) 是流(Stream)处理的核心方法,用于将可读流(Readable Stream)的数据直接传输到可写流(Writable Stream)。其作用本质是​​高效、自动地处理数据流动​​,尤其在处理大文件或实时数据时至关重要

  • 自动数据传递​​
    rs.pipe(ws) 会将可读流 rs 产生的数据块(chunks)自动传输到可写流 ws 中,无需手动监听 data 事件或循环读取数据
const fs = require('fs');
const rs = fs.createReadStream('source.txt');
const ws = fs.createWriteStream('copy.txt');

rs.pipe(ws); // 自动将可读流的数据传输到可写流

  • ​​背压控制
  • 当写入流处理速度慢于读取流时(如目标磁盘性能不足),pipe() 会自动暂停读取流(rs.pause()),待写入流触发 drain 事件后再恢复读取(rs.resume()),避免内存溢出
  • 当写入流处理速度快于读取流时,pipe() 会自动调节读取流的速度,以匹配写入流的处理能力
  • 事件自动绑定
  • pipe() 内部自动处理以下事件:
  • data:读取数据块并写入目标文件。
  • end:结束写入流(ws.end())。
  • error:统一传递错误到目标流
const fs = require('fs');
const rs = fs.createReadStream('source.mp4');
const ws = fs.createWriteStream('copy.mp4');
const stats = fs.statSync('source.mp4');
const totalSize = stats.size;
let copiedSize = 0;

rs.on('data', (chunk) => {
  copiedSize += chunk.length;
  const percent = Math.round((copiedSize / totalSize) * 100);
  console.log(`复制进度: ${percent}%`);
});

rs.pipe(ws); // 保持管道连接
完整案例
const fs = require('fs');
const path = require('path');

// 安全路径处理
const filePath = path.join(__dirname, 'data', 'file.txt');
console.log('文件路径:', filePath);
// 写入文件
fs.writeFile(filePath, 'Hello World', err => {
  if (err) return console.error('写入失败', err);
  
  // 读取文件
  fs.readFile(filePath, 'utf-8', (err, data) => {
    console.log('文件内容:', data);
    
    // 追加内容
    fs.appendFile(filePath, '\nNew content', err => {
      // 查看文件状态
      fs.stat(filePath, (err, stats) => {
        console.log('文件大小:', stats.size, 'bytes');
      });
    });
  });
});

// 流式文件复制
const rs = fs.createReadStream('source.mp4');
const ws = fs.createWriteStream('copy.mp4');
rs.pipe(ws);

网站公告

今日签到

点亮在社区的每一天
去签到