Node.js FS 模組:檔案系統操作基礎
Node.js 的 fs (File System) 模組是與電腦檔案系統互動的核心工具。它讓你能夠像作業系統一樣,進行檔案的讀取、寫入、刪除、重新命名以及權限管理。
核心設計:三種操作模式
在 fs 模組中,幾乎所有功能都具備三種實作方式。理解它們的差異是寫出高效能程式碼的第一步:
- 非同步回呼 (Callback):傳統做法,程式不會被阻塞,執行完後呼叫回呼函式。
- 同步阻塞 (Synchronous):函式名帶有
Sync字尾。會卡住整個主執行緒,直到操作完成。 - Promise 模式 (推薦):位於
fs.promises下,可配合async/await使用,兼具效能與可讀性。
金律:在開發 Web 伺服器(如 Express)時,絕不要在請求處理過程中使用同步 (
Sync) 版本。這會導致伺服器無法服務同時進來的其他用戶。讀取檔案 (Reading Files)
如果你不指定編碼,Node.js 預設會回傳原始的 Buffer 資料。
const fs = require('fs');
// 1. 傳統 Callback 寫法
fs.readFile('hello.txt', 'utf8', (err, data) => {
if (err) return console.error(err);
console.log('讀取成功:', data);
});
// 2. 現代 Promise 寫法 (最推薦)
const fsPromises = require('fs').promises;
async function read() {
const data = await fsPromises.readFile('hello.txt', 'utf8');
}
寫入與附加內容 (Writing & Appending)
writeFile:會建立新檔案。如果檔案已存在,會直接覆蓋舊內容。appendFile:如果檔案已存在,會在原有的內容後面累加。
// 寫入檔案
fs.writeFile('output.txt', '這會覆蓋原檔案', (err) => {
if (err) throw err;
});
// 附加日誌
const log = `[${new Date().toISOString()}] 系統事件\n`;
fs.appendFile('app.log', log, (err) => {
if (err) throw err;
});
檔案狀態與存在檢查
在舊版 Node.js 中常用 fs.exists,但現在已被廢棄。正確做法是使用 fs.stat 或檢查讀寫權限的 fs.access。
// 獲取檔案詳細資訊
fs.stat('image.jpg', (err, stats) => {
if (err) return console.log('找不到檔案');
console.log('檔案大小:', stats.size, '位元組');
console.log('建立時間:', stats.birthtime);
console.log('是否為目錄:', stats.isDirectory());
});
常見編碼問題小筆記
在處理文字檔案時,務必明確指定 'utf8' 編碼。如果處理的是圖片、音訊或二進位封包,則省略編碼以獲取 Buffer。
- 文字型讀取:
fs.readFile(path, 'utf8', ...) - 二進位讀取:
fs.readFile(path, ...)(返回 Buffer)
總結
- 除非是單機執行且簡單的 CLI 腳本,否則一律使用非同步版本。
- 現代專案建議全面導入
fs.promises。 - 處理大型檔案(如 100MB 以上)時,請參考 Stream 串流教學 以節省記憶體。