Node.js 编程实战:文件系统(fs)模块详解

在服务端开发中,文件操作是不可避免的需求。无论是读取配置、写入日志、上传文件、管理缓存,还是处理图片和文档,都离不开文件系统操作。Node.js 通过内置的 fs 模块提供了一整套文件读写能力,使 JavaScript 能够高效地与操作系统文件系统交互。


一、fs 模块概述

fs 模块是 Node.js 的核心模块之一,用于访问本地文件系统。它提供了文件读取、写入、创建、删除、复制、重命名、目录管理等一整套能力。

在 Node.js 中,fs 不需要安装,直接通过以下方式引入即可使用:

js 复制代码
const fs = require('fs')

从 Node.js 10 之后,fs 模块同时支持回调方式、Promise 方式以及同步方式,开发者可以根据场景灵活选择。


二、三种使用方式对比

1. 回调方式

这是最早期的使用形式,通过回调函数处理结果:

js 复制代码
fs.readFile('a.txt', 'utf8', (err, data) => {
  if (err) throw err
  console.log(data)
})

缺点是嵌套较多,代码可读性在复杂场景中会下降。


2. Promise 方式

Node.js 提供了 fs.promises 接口,更适合现代开发风格:

js 复制代码
const fs = require('fs/promises')

async function read() {
  const data = await fs.readFile('a.txt', 'utf8')
  console.log(data)
}

这种方式可以结合 async / await 使用,可读性较好。


3. 同步方式

js 复制代码
const data = fs.readFileSync('a.txt', 'utf8')

同步方式简单直接,但会阻塞进程,不适合高并发服务,仅适用于脚本或初始化阶段。


三、常用文件操作示例

1. 写入文件

js 复制代码
fs.writeFile('log.txt', 'hello', err => {
  if (err) console.error(err)
})

2. 判断文件是否存在

js 复制代码
fs.access('a.txt', err => {
  if (err) console.log('不存在')
})

3. 创建目录

js 复制代码
fs.mkdir('logs', { recursive: true }, err => {})

4. 删除文件

js 复制代码
fs.unlink('log.txt', err => {})

5. 读取目录

js 复制代码
fs.readdir('./logs', (err, files) => {
  console.log(files)
})

四、流式操作:处理大文件必备

当读取大文件时,如果一次性加载全部内容到内存,很容易导致内存暴涨。

Node.js 提供了流式接口:

js 复制代码
const readStream = fs.createReadStream('big.txt')
const writeStream = fs.createWriteStream('copy.txt')

readStream.pipe(writeStream)

这种方式可以边读边写,适合处理视频、压缩包等大文件。


五、文件监听与变更监控

fs 还支持监听文件变化:

js 复制代码
fs.watch('config.json', () => {
  console.log('文件发生变化')
})

该功能在热加载、配置动态更新中非常有用。


六、路径问题与跨平台兼容

配合 path 模块可避免路径问题:

js 复制代码
const path = require('path')
const filePath = path.join(__dirname, 'a.txt')

避免硬编码路径,有助于兼容不同操作系统。


七、常见坑点总结

文件编码未指定,导致中文乱码。 忘记处理异常,程序意外崩溃。 同步 API 用在 Web 服务中,导致阻塞。 路径拼接写死,引发跨平台问题。 大文件用 readFile 直接读入内存。


八、总结

fs 模块是 Node.js 与操作系统交互的基础能力。 小文件用 Promise API。 大文件使用流处理。 服务环境避免阻塞式操作。 涉及路径务必结合 path。

掌握 fs 模块,是迈向 Node.js 后端开发的重要一步。


相关推荐
代龙涛6 小时前
WordPress Query 查询机制详解(WP_Query)
开发语言·后端·php·wordpress
程序员cxuan6 小时前
不是,为啥这个模型突然就爆火了??
人工智能·后端·程序员
知守观6 小时前
技术考古:iBATIS 2.3.4 时代的持久层,是如何用 Map 玩转 307 个存储过程的?
java·后端·mybatis
程序员cxuan6 小时前
国产 GPU 能不能打,重点在软件栈
人工智能·后端·程序员
the局外人6 小时前
Python 中使用 SSE 实现大模型流式输出
后端·python·llm
苍何7 小时前
用 WorkBuddy + LibTV 做 AI 视频,干活有点猛啊!(附教程)
后端
苍何7 小时前
我的新书冲上京东热榜第一了!
后端
掘金者阿豪8 小时前
MongoDB迁移到金仓数据库:商品属性继续灵活存,订单报表交给 SQL
前端·后端
zhoujungis8 小时前
限流算法实测:固定窗口 2 倍溢出、令牌桶突刺 | 尘世栈帧
后端
小蒜学长8 小时前
编程语言在线学习平台的设计与实现(代码+数据库+LW)
java·spring boot·后端·编程语言在线学习平台·在线编码