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


相关推荐
the局外人几秒前
FastAPI中jwt的基本使用与实践
后端·python·fastapi
FullStackGeek23 分钟前
微信缴费APIV3接入
后端
灯澜忆梦29 分钟前
【Go Zap 日志库】#1 |快速上手 + 配置详解
开发语言·后端·golang
m0_5873830034 分钟前
无人自助拼豆系统从需求分析到落地部署全流程实战开发指南
java·经验分享·后端·struts·小程序·架构·需求分析
Rain的Java大神之路44 分钟前
被问麻了!Function Calling、MCP、Skill 到底啥关系?一张图讲透三层架构,附 Java 生产落地全流程+30个坑
java·后端·ai编程
云和数据.ChenGuang2 小时前
用 Claude Code 重构遗留系统:从评估到落地的完整指南
java·人工智能·spring boot·后端·重构·springai
豆角焖肉2 小时前
SpringBoot 集成腾讯 AI 人脸识别
人工智能·spring boot·后端·人脸识别·腾讯 ai·base64 图片
付威20232 小时前
如果你想拥有自己的 Agent,为什么值得从 rpi 开始
后端
可乐ea3 小时前
2000 个智能体把 Agent 重写成 Rust:编排流水线拆解
开发语言·后端·rust·多智能体协作·ai编程助手·智能体编排·rust重写
用户72757483196503 小时前
02-变量、常量和字符串:len("Hello, 世界") 为什么不是 9?
后端