极简 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