极简 Node.js 入门 - 3.2 文件读取
2020-08-20 19:08
1381 查看
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node
Node.js 提供了多种读取文件的 API
fs.readFile
fs.readFile(path[, options], callback)是最常用的读取文件方法,用于异步读取文件的全部内容
const fs = require('fs'); fs.readFile('./test.txt', (err, data) => { if (err) throw err; console.log(data); });
回调会传入两个参数 (err, data),其中 data 是文件的内容,如果
options是字符串,则它指定字符编码:
fs.readFile('./test.txt', 'utf8', callback);
options 可以设置为对象
fs.readFile('./test.txt', { encoding: 'utf8', flag: 'r' }, callback);
fs.open、fs.read、fs.close
fs.readFile 使用相当简单,在大部分读取小文件的时候我们都应该使用这个方法,但 fs.readFile() 会把文件全部内容读取,如果想精确读取部分文件内容,Node.js 也提供了类似 C 语言 fopen、fgetc、fclose 的操作
在 Node.js 中读取一个文件同样有三步
- fs.open():分配(打开)文件描述符
- fs.read():读取文件内容
- fs.close():关闭文件描述符
> 在 POSIX 每个打开的文件系统都分配了一个称为文件描述符的数字。 文件系统操作使用文件描述符来标识和跟踪每个特定的文件。一旦被分配,则文件描述符可用于从文件读取数据、向文件写入数据、或请求关于文件的信息 > buffer 相关知识需要先行查看 > [Buffer](https://www.yuque.com/sunluyong/node/buffer) 章节 ### fs.open(path[, flags[, mode]], callback) 通过 fs.open 方法可以打开一个文件,获取分配到的文件描述符,方法参数含义:
- path 文件路径(实际还能是 Buffer、URL)
- flags 文件标志位,默认值 r(read 缩写),标识文件用于读取
- mode 文件模式,默认值 0o666 (rw-)可读写
- callback err
- fd 分配到的文件描述符 (file description)
fs.read(fd, [options,] callback)
fs.read 用于从文件描述符中读取数据,方法参数含义:
- fd 文件描述符
- options 可选项,不设置使用下述默认值
buffer:数据(从 fd 读取)将被写入的缓冲区,默认会申请一个新的缓冲区
Buffer.alloc(16384)
- offset:buffer 开始写入的偏移量,默认值为 0
- length:需要读取的字节数,默认使用
buffer.length
- position:从文件中开始读取数据的位置;如果 position 为 null,则从当前文件位置读取,并重置文件位置到上次位置;如果 position 是整数,则文件位置会被保持。默认值为 null
-
err
fs.read 还有一个需要把参数写全的重载 fs.read(fd, buffer, offset, length, position, callback)
fs.close(fs, callback)
fs.close 用于关闭文件描述符,大多数操作系统都会限制同时打开的文件描述符数量,因此当操作完成时关闭描述符非常重要。 如果不这样做将导致内存泄漏,最终导致应用程序崩溃
demo
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 已关闭
- 程序第一次从第 11 个字节开始读取
test.txt
内容,一共读取 26 个字节 - 第一次读取设置了 position 属性,读取完成后文件指针位置被重置为 0
- 第二次读取没有设置 position 读取一个字节后,文件位置停留在 1
- 第三次读取直接从文件位置 1 开始读取
除非希望精确控制,否则不要使用这种方式读取文件,手工控制缓冲区、文件位置指针很容易出现各种意外状况
fs.createReadStream
对于大文件读取一般使用流的方式,关于流的简单原理在后面章节有专门介绍,本章介绍一下使用 fs 创建可读文件流
fs.createReadStream(path[, options])
- path
- options(比较常用的有)
-
fd: 如果指定了 fd,则 ReadStream 会忽略 path 参数,使用指定的文件描述符(不会再次触发 open 事件)
- autoClose: 默认值: true,文件读取完成或者出现异常时是否自动关闭文件描述符
- start: 开始读取位置
- end: 结束读取位置
- highWaterMark: 默认值: 64 * 1024,普通可读流一般是 16k
流的各个状态会有对应的事件抛出,还是读取上文用过的
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
相关文章推荐
- Node.js开发入门—HTTP文件服务器
- node.js(4)异步式I/O与事件式编程 nodejs文件读取
- 拥抱Node.js 8.0,N-API入门极简例子
- Node.js入门:文件查找机制
- 关于node.js读取文件以及操作流文件的个人理解
- node.js读取本地的文件
- node.js学习之读取文件初步
- node.js 读取文件详解 readFile
- Node.Js Buffer类(缓冲区)-(三)文件读取实例
- Node.js (一)—— 概念、环境安装、读取文件、模块系统(require)、使用http创建简单的服务器、ip地址和端口号概念
- node.js读取文件到字符串的方法
- ActiveMQ + NodeJS + Stomp 极简入门
- Node.js readline 逐行读取、写入文件内容的示例
- node.js 读取文件--createReadStream
- ActiveMQ + NodeJS + Stomp 极简入门
- node.js 读取文件
- nw.js node-webkit系列(20)拖动文件到页面并读取文件信息
- ActiveMQ + NodeJS + Stomp 极简入门
- node.js 读取文件内容
- node.js实现逐行读取文件内容的代码