简介:为什么在 Node.js 中处理文件系统很重要
在现代 Web 开发中,几乎无法避免与文件系统打交道。无论是上传用户头像、生成日志、处理 CSV 报告,还是读取配置文件——Node.js 都提供了强大的内置 fs(文件系统)模块来处理这些任务。
与浏览器 JavaScript 不同(出于安全原因,浏览器中文件访问受到严格限制),Node.js 让你能够完全控制服务器的文件系统。在本文中,我们将通过实际示例分解关键操作,帮助你自信地处理文件和文件夹。
你将学到:
- 如何读取和写入文件(同步和异步方式)
- 如何使用流处理大文件
- 如何创建、重命名和删除文件夹
- 如何正确处理错误和路径
1. 基础:读取和写入文件
fs 模块提供了三种主要的文件处理方式:同步方式、异步方式(回调函数)和基于 Promise 的方式。推荐使用基于 Promise 的异步方式(fs.promises)——它不会阻塞事件循环,并且更易于阅读。
1.1 读取文件
读取整个文件最简单的方法是使用 readFile。
const fs = require('fs').promises;
async function readConfig() { try { const data = await fs.readFile('./config.json', 'utf-8'); const config = JSON.parse(data); console.log('Port:', config.port); } catch (err) { console.error('Read error:', err.message); }}
readConfig();重要提示:指定编码('utf-8'),否则将返回一个 Buffer 对象。
1.2 写入文件
使用 writeFile(覆盖文件)或 appendFile(追加到末尾)进行写入。
const fs = require('fs').promises;
async function saveLog(message) { const logLine = `[${new Date().toISOString()}] ${message}`; try { await fs.appendFile('./app.log', logLine); console.log('Log saved'); } catch (err) { console.error('Write error:', err); }}
saveLog('Server started');2. 处理大文件:流
想象一下你需要读取一个 2 GB 的文件。使用 readFile 方法会将其全部加载到内存中,这可能导致内存泄漏。对于这种情况,可以使用流(fs.createReadStream 和 fs.createWriteStream)。
流会分块处理数据,而不会将整个文件存储在内存中。
示例:复制大文件
const fs = require('fs');const path = require('path');
const source = path.join(__dirname, 'bigfile.zip');const destination = path.join(__dirname, 'copy.zip');
const readStream = fs.createReadStream(source);const writeStream = fs.createWriteStream(destination);
readStream.on('data', (chunk) => { console.log(`Read ${chunk.length} bytes`); writeStream.write(chunk);});
readStream.on('end', () => { writeStream.end(); console.log('Copying completed');});
readStream.on('error', (err) => { console.error('Read error:', err);});提示:对于复制操作,更方便的方法是使用 stream 模块内置的 pipeline 方法——它能够自动处理错误并关闭流。
3. 管理目录
处理文件夹同样重要。Node.js 允许你创建、读取和删除目录。
3.1 创建和检查文件夹
const fs = require('fs').promises;
async function ensureDir(dirPath) { try { await fs.mkdir(dirPath, { recursive: true }