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 后端开发的重要一步。


相关推荐
candyTong31 分钟前
Claude Code 的 Edit 工具是怎么工作的
javascript·后端·架构
GetcharZp2 小时前
GitHub 2.4 万 Star!D2 正在重新定义程序员画图方式
后端
zhangxingchao3 小时前
多 Agent 架构到底怎么选?从 Claude Agent Teams、Cognition/Devin 到工程落地原则
前端·人工智能·后端
IT_陈寒3 小时前
SpringBoot那个自动配置的坑,害我排查到凌晨三点
前端·人工智能·后端
ServBay3 小时前
OpenCode 和它的7款必备插件
后端·github·ai编程
ping某3 小时前
逐字节拆解 tcpdump
后端
阿凡9807304 小时前
花 100 dollar,用 Claude 打通 EasyEDA&Fusion 双向同步
后端·程序员
irving同学462384 小时前
从零搭建生产级 RAG:Embedding、Chunking、Hybrid Search 与 Reranker
前端·后端
她的男孩4 小时前
从零搭一个企业后台,为什么我把能力拆成 Starter 和 Plugin
java·后端·架构
胡志辉4 小时前
本地 AI 编码助手从 0 配起来:先选模型,再接 Ollama、VS Code、Claude Code 和 Codex
前端·后端