極簡 Node.js 入門系列教程:https://www.yuque.com/sunluyong/nodejavascript
本文更佳閱讀體驗:https://www.yuque.com/sunluyong/node/fs-readhtml
fs.readFile(path[, options], callback)
是最經常使用的讀取文件方法,用於異步讀取文件的所有內容node
const fs = require('fs'); fs.readFile('./test.txt', (err, data) => { if (err) throw err; console.log(data); });
回調會傳入兩個參數 (err, data),其中 data 是文件的內容,若是 options
是字符串,則它指定字符編碼:api
fs.readFile('./test.txt', 'utf8', callback);
options 能夠設置爲對象異步
fs.readFile('./test.txt', { encoding: 'utf8', flag: 'r' }, callback);
fs.readFile 使用至關簡單,在大部分讀取小文件的時候咱們都應該使用這個方法,但 fs.readFile() 會把文件所有內容讀取,若是想精確讀取部分文件內容,Node.js 也提供了相似 C 語言 fopen、fgetc、fclose 的操做async
在 Node.js 中讀取一個文件一樣有三步ui
fs.read 用於從文件描述符中讀取數據,方法參數含義:編碼
Buffer.alloc(16384)
buffer.length
fs.read 還有一個須要把參數寫全的重載 fs.read(fd, buffer, offset, length, position, callback)操作系統
fs.close 用於關閉文件描述符,大多數操做系統都會限制同時打開的文件描述符數量,所以當操做完成時關閉描述符很是重要。 若是不這樣作將致使內存泄漏,最終致使應用程序崩潰
test.txt
0123456789 abcdefghigklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
const fs = require('fs'); const promisify = require('util').promisify; const open = promisify(fs.open); const read = promisify(fs.read); const close = promisify(fs.close); async function test() { const fd = await open('./test.txt'); const readOptions = { // buffer: Buffer.alloc(26), 異步調用默承認以不設置,若是但願讀取的字節寫入指定的緩衝區能夠指定 position: 11, // 從第 11 個字節開始讀取,讀取後文件位置被重置 length: 26, // 讀取 26 個字節 }; const { bytesRead: bytesRead1, buffer: buf1 } = await read(fd, readOptions); console.log(`第一次讀取字節數: ${bytesRead1}`); console.log(`第一次讀取數據內容: ${buf1.toString()}`); // 不指定 position,文件位置每次讀取後會保持 const { bytesRead: bytesRead2, buffer: buf2 } = await read(fd, { length: 1 }); console.log(`第二次從文件重置後位置讀取 ${bytesRead2} 字節內容: ${buf2.toString()}`); const { bytesRead: bytesRead3, buffer: buf3 } = await read(fd, { length: 1 }); console.log(`第三次從文件當前位置讀取 ${bytesRead3} 字節內容: ${buf3.toString()}`); await close(fd); console.log(`文件描述符 ${fd} 已關閉`); } test();
第一次讀取字節數: 26 第一次讀取數據內容: abcdefghigklmnopqrstuvwxyz 第二次從文件重置後位置讀取 1 字節內容: 0 第三次從文件當前位置讀取 1 字節內容: 1 文件描述符 20 已關閉
test.txt
內容,一共讀取 26 個字節
除非但願精確控制,不然不要使用這種方式讀取文件,手工控制緩衝區、文件位置指針很容易出現各類意外情況
對於大文件讀取通常使用流的方式,關於流的簡單原理在後面章節有專門介紹,本章介紹一下使用 fs 建立可讀文件流fs.createReadStream(path[, options])
流的各個狀態會有對應的事件拋出,仍是讀取上文用過的 test.txt
文件
const fs = require('fs'); const rs = fs.createReadStream('./test.txt', { start: 11, end: 36 }); rs.on('open', fd => { console.log(`文件描述符 ${fd} 已分配`); }); rs.on('ready', () => { console.log('文件已準備好'); }); rs.on('data', chunk => { console.log('讀取文件數據:', chunk.toString()); }); rs.on('end', () => { console.log('文件讀取完成'); }); rs.on('close', () => { console.log('文件已關閉'); }); rs.on('error', (err) => { console.log('文件讀取發生發生異常:', err.stack); });
文件描述符 20 已分配 文件已準備好 讀取文件數據: abcdefghigklmnopqrstuvwxyz 文件讀取完成 文件已關閉
可讀流詳細操做參考:可讀流 https://www.yuque.com/sunluyong/node/readable