Node.js-Buffer
# Node.js-Buffer
JavaScript 语言自身只有字符串数据类型,没有二进制数据类型
但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区
当数据到达的时间比数据理出的时间快的时候,这个时候我们处理数据就需要等待了
如果处理数据的时间比到达的时间快,这一时刻仅仅到达了一小部分数据,那这小部分数据需要等待剩下的数据填满,然后再送过去统一处理
在一些公交站,公车在没有装满乘客前是不会发车的,或者在特定的时刻才会发车。不论何时,早到的乘客都必须等待,直到公车接到指令可以发车。当乘客到站,发现公车已经装满,或者已经开走,他就必须等待下一班车次
有一个等待的区域就是Node.js中的Buffer Node.js不能控制数据什么时候传输过来,传输速度
就好像公交车站无法控制人流量一样,他只能决定什么时候发送数据
# Buffer 与字符编码
Node.js 目前支持的字符编码包括:
- ascii - 仅支持 7 位 ASCII 数据。如果设置去掉高位的话,这种编码是非常快的
- utf8 - 多字节编码的 Unicode 字符。许多网页和其他文档格式都使用 UTF-8
- utf16le - 2 或 4 个字节,小字节序编码的 Unicode 字符。支持代理对(U+10000 至 U+10FFFF)
- ucs2 - utf16le 的别名
- base64 - Base64 编码
- latin1 - 一种把 Buffer 编码成一字节编码的字符串的方式
- binary - latin1 的别名
- hex - 将每个字节编码为两个十六进制字符
const buf = Buffer.from('runoob', 'ascii');
// 输出 cnVub29i
console.log(buf.toString('base64'));
1
2
3
4
2
3
4
# 创建 Buffer 类
// Buffer.alloc(size[, fill[, encoding]]) 返回一个指定大小的 Buffer 实例,如果没有设置 fill,则默认填满 0
// 创建一个长度为 10、且用 0 填充的 Buffer。
const buf1 = Buffer.alloc(10);
// 创建一个长度为 10、且用 0x1 填充的 Buffer。
const buf2 = Buffer.alloc(10, 1);
// Buffer.allocUnsafe(size): 返回一个指定大小的 Buffer 实例,但是它不会被初始化,所以它可能包含敏感的数据
// 创建一个长度为 10、且未初始化的 Buffer。
// 这个方法比调用 Buffer.alloc() 更快,
// 但返回的 Buffer 实例可能包含旧数据,
// 因此需要使用 fill() 或 write() 重写。
const buf3 = Buffer.allocUnsafe(10);
// Buffer.allocUnsafeSlow(size)
// Buffer.from(array): 返回一个被 array 的值初始化的新的 Buffer 实例(传入的 array 的元素只能是数字,不然就会自动被 0 覆盖)
// 创建一个包含 [0x1, 0x2, 0x3] 的 Buffer。
const buf4 = Buffer.from([1, 2, 3]);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 写入缓冲区
# 语法
buf.write(string[, offset[, length]][, encoding])
1
# 参数
- string - 写入缓冲区的字符串
- offset - 缓冲区开始写入的索引值,默认为 0
- length - 写入的字节数,默认为 buffer.length
- encoding - 使用的编码。默认为 'utf8'
# 返回值
返回实际写入的大小。如果 buffer 空间不足, 则只会写入部分字符串
# 实例
buf = Buffer.alloc(256);
len = buf.write("www.runoob.com");
console.log("写入字节数 : "+ len);
// 输入结果
$node main.js
写入字节数 : 14
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 从缓冲区读取数据
# 语法
buf.toString([encoding[, start[, end]]])
1
# 参数
- encoding - 使用的编码。默认为 'utf8'
- start - 指定开始读取的索引位置,默认为 0
- end - 结束位置,默认为缓冲区的末尾
# 返回值
解码缓冲区数据并使用指定的编码返回字符串
# 实例
buf = Buffer.alloc(26);
for (var i = 0 ; i < 26 ; i++) {
buf[i] = i + 97;
}
console.log( buf.toString('ascii')); // 输出: abcdefghijklmnopqrstuvwxyz
console.log( buf.toString('ascii',0,5)); //使用 'ascii' 编码, 并输出: abcde
console.log( buf.toString('utf8',0,5)); // 使用 'utf8' 编码, 并输出: abcde
console.log( buf.toString(undefined,0,5)); // 使用默认的 'utf8' 编码, 并输出: abcde
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 将 Buffer 转换为 JSON 对象
# 语法
buf.toJSON()
// 当字符串化一个 Buffer 实例时,JSON.stringify() 会隐式地调用该 toJSON()。
1
2
2
# 返回值
buf.toJSON()
1
# 实例
const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]);
const json = JSON.stringify(buf);
// 输出: {"type":"Buffer","data":[1,2,3,4,5]}
console.log(json);
const copy = JSON.parse(json, (key, value) => {
return value && value.type === 'Buffer' ?
Buffer.from(value.data) :
value;
});
// 输出: <Buffer 01 02 03 04 05>
console.log(copy);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 缓冲区合并
# 语法
Buffer.concat(list[, totalLength])
1
# 参数
- list - 用于合并的 Buffer 对象数组列表
- totalLength - 指定合并后Buffer对象的总长度
# 返回值
返回一个多个成员合并的新 Buffer 对象。
# 实例
var buffer1 = Buffer.from(('hhh'));
var buffer2 = Buffer.from(('www'));
var buffer3 = Buffer.concat([buffer1,buffer2]);
console.log("buffer3 内容: " + buffer3.toString());
// buffer3 内容: hhhwww
1
2
3
4
5
6
2
3
4
5
6
# 缓冲区比较
# 语法
buf.compare(otherBuffer);
1
# 参数
- otherBuffer - 与 buf 对象比较的另外一个 Buffer 对象
# 返回值
返回一个数字,表示 buf 在 otherBuffer 之前,之后或相同
# 实例
var buffer1 = Buffer.from('ABC');
var buffer2 = Buffer.from('ABCD');
var result = buffer1.compare(buffer2);
if(result < 0) {
console.log(buffer1 + " 在 " + buffer2 + "之前");
}else if(result == 0){
console.log(buffer1 + " 与 " + buffer2 + "相同");
}else {
console.log(buffer1 + " 在 " + buffer2 + "之后");
}
// ABC在ABCD之前
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 拷贝缓冲区
# 语法
buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]])
1
# 参数
- targetBuffer - 要拷贝的 Buffer 对象
- targetStart - 数字, 可选, 默认:
- sourceStart - 数字, 可选, 默认:
- sourceEnd - 数字, 可选, 默认: buffer.length
# 返回值
没有返回值
# 实例
var buf1 = Buffer.from('abcdefghijkl');
var buf2 = Buffer.from('RUNOOB');
//将 buf2 插入到 buf1 指定位置上
buf2.copy(buf1, 2);
console.log(buf1.toString());
// abRUNOOBijkl
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 缓冲区裁剪
# 语法
buf.slice([start[, end]])
1
# 参数
- start - 数字, 可选, 默认: 0
- end - 数字, 可选, 默认: buffer.length
# 返回值
返回一个新的缓冲区,它和旧缓冲区指向同一块内存,但是从索引 start 到 end 的位置剪切
# 实例
var buffer1 = Buffer.from('runoob');
// 剪切缓冲区
var buffer2 = buffer1.slice(0,2);
console.log("buffer2 content: " + buffer2.toString());
// buffer2 content: ru
1
2
3
4
5
6
2
3
4
5
6
# 缓冲区长度
# 语法
buf.length;
1
# 返回值
返回 Buffer 对象所占据的内存长度
# 实例
var buffer = Buffer.from('www.runoob.com');
// 缓冲区长度
console.log("buffer length: " + buffer.length);
// buffer length: 14
1
2
3
4
5
2
3
4
5
上次更新: 2024/08/14, 04:14:33