一、Buffer 类的用处
- JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。
- 但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。
- 在 Node.js 中,Buffer 类是随 Node 内核一起发布的核心库。Buffer 库为 Node.js 带来了一种存储原始数据的方法,可以让 Node.js 处理二进制数据,每当需要在 Node.js 中处理I/O操作中移动的数据时,就有可能使用 Buffer 库。原始数据存储在 Buffer 类的实例中。一个 Buffer 类似于一个整数数组,但它对应于 V8 堆内存之外的一块原始内存。
- 简单来说就是存放二进制数据的缓冲池。
二、Buffer 与字符编码
- 转化方法from
- 两个参数:字符串、字符串的编码格式
let buff=Buffer.from("a","ascii");
console.log(buff);//<Buffer 61>
console.log(buff.toString());//a
| 编码格式 | 支持 |
|---|
| ascii | 仅支持 7 位 ASCII 数据。如果设置去掉高位的话,这种编码是非常快的。 |
| utf8 | 多字节编码的 Unicode 字符。许多网页和其他文档格式都使用 UTF-8 。 |
| utf16le | 2 或 4 个字节,小字节序编码的 Unicode 字符。支持代理对(U+10000 至 U+10FFFF)。 |
| ucs2 | utf16le 的别名。 |
| base64 | Base64 编码。 |
| latin1 | 一种把 Buffer 编码成一字节编码的字符串的方式。 |
| binary | latin1 的别名。 |
| hex | 将每个字节编码为两个十六进制字符。 |
三、创建 Buffer 类
| 方法 | 用法 |
|---|
| Buffer.alloc(size[, fill[, encoding]]) | 返回一个指定大小的 Buffer 实例,如果没有设置 fill,则默认填满 0 |
| Buffer.allocUnsafe(size) | 返回一个指定大小的 Buffer 实例,但是它不会被初始化,所以它可能包含敏感的数据 |
| Buffer.allocUnsafeSlow(size) | |
| Buffer.from(array) | 返回一个被 array 的值初始化的新的 Buffer 实例(传入的 array 的元素只能是数字,不然就会自动被 0 覆盖) |
| Buffer.from(arrayBuffer[, byteOffset[, length]]) | 返回一个新建的与给定的 ArrayBuffer 共享同一内存的 Buffer。 |
| Buffer.from(buffer) | 复制传入的 Buffer 实例的数据,并返回一个新的 Buffer 实例 |
| Buffer.from(string[, encoding]) | 返回一个被 string 的值初始化的新的 Buffer 实例 |
- Buffer.alloc有三个参数:指定长度、填充的值(不写默认值为0)、前面值的编码
// 创建一个长度为 10、且用 0 填充的 Buffer。
let buf1=Buffer.alloc(10);
console.log(buf1);//<Buffer 00 00 00 00 00 00 00 00 00 00>
// 创建一个长度为 10、且用 0x1 填充的 Buffer。
let buf2=Buffer.alloc(10,1);
console.log(buf2);//<Buffer 01 01 01 01 01 01 01 01 01 01>
- Buffer.allocUnsafe(size)
- 只有一个参数size
- 创建一个长度为 10、且未初始化的 Buffer。这个方法比调用 Buffer.alloc() 更快,但返回的 Buffer 实例可能包含旧数据,因此需要使用 fill() 或 write() 重写。
let buf3=Buffer.allocUnsafe(10);
console.log(buf3);//<Buffer 02 01 03 00 00 44 60 00 01 10>
四、写入缓冲区
1. 语法
- 写入 Node 缓冲区的语法如下所示:
- buf.write(string[, offset[, length]][, encoding])
2. 参数
- (1)string - 写入缓冲区的字符串。
- (2)offset - 缓冲区开始写入的索引值,默认为 0 。
- (3)length - 写入的字节数,默认为 buffer.length
- (4)encoding - 使用的编码。默认为 ‘utf8’ 。
- 根据 encoding 的字符编码写入 string 到 buf 中的 offset 位置。 length 参数是写入的字节数。 如果 buf 没有足够的空间保存整个字符串,则只会写入 string 的一部分。 只部分解码的字符不会被写入。
3. 返回值
- 返回实际写入的大小。如果 buffer 空间不足, 则只会写入部分字符串。
// 建立固定长度的编码
let buf4=Buffer.alloc(20);
// 写入值
let len=buf4.write("hello world");
console.log(len);//11
console.log(buf4);//<Buffer 68 65 6c 6c 6f 20 77 6f 72 6c 64 00 00 00 00 00 00 00 00 00>
console.log(buf4.toString());//hello world
五、从缓冲区读取数据
1. 语法
- 读取 Node 缓冲区数据的语法如下所示:
- buf.toString([encoding[, start[, end]]])
2. 参数
- encoding - 使用的编码。默认为 ‘utf8’ 。
- start - 指定开始读取的索引位置,默认为 0。
- end - 结束位置,默认为缓冲区的末尾。
3. 返回值
let buf5=Buffer.alloc(26);
for(var i=0;i<26;i++){
buf5[i]=i+97;
}
console.log(buf5.toString('ascii'));//abcdefghijklmnopqrstuvwxyz
console.log(buf5.toString('ascii',0,5));//abcde
console.log(buf5.toString('utf-8',0,5));//abcde
console.log(buf5.toString(undefined,0,5));//abcde
六、将 Buffer 转换为 JSON 对象
1. 语法
- 将 Node Buffer 转换为 JSON 对象的函数语法格式如下:
- buf.toJSON()
- 当字符串化一个 Buffer 实例时,JSON.stringify() 会隐式地调用该 toJSON()。
2. 返回值
// 建立json数据
let json={"id":1,"name":"张三"};
let buff=Buffer.alloc(1024);
buff.write(JSON.stringify(json));
console.log(buff);//<Buffer 7b 22 69 64 22 3a 31 2c 22 6e 61 6d 65 22 3a 22 e5 bc a0 e4 b8 89 22 7d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... 974 more bytes>
// toJSON不是转成原数据json,而是把json buffer数据转化成json格式。
console.log(buff.toJSON());
console.log(buff.toString());//{"id":1,"name":"张三"}
七、缓冲区合并
1. 语法
- Node 缓冲区合并的语法如下所示:
- Buffer.concat(list[, totalLength])
2. 参数
- list - 用于合并的 Buffer 对象数组列表。
- totalLength - 指定合并后Buffer对象的总长度。
3. 返回值
let buf6=Buffer.from("张三");
let buf7=Buffer.from("hello world");
let buf8=Buffer.concat([buf6,buf7]);
console.log(buf8.toString());//张三hello world