缓冲流
- 一、node.js Buffer(缓冲区)
- 二、Buffer类存在的意义
- 三、Buffer类的基本操作
- 1、 创建Buffer类
- 2、写入缓冲区
- 3、剪裁缓冲区
- 4、将 Buffer 转换为字符串
- 5、拼接Buffer类
- 6、检查字符编码名称
- 7、将 Buffer 转换为 JSON 对象
一、node.js Buffer(缓冲区)
JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,定义了一个Buffer
类,该类用来创建一个专门存放二进制数据的缓存区。
举一个简单的场景:当我们观看腾讯视频时,红线会超过观看点:也就是下载数据的速度比查看数据的速度快,且浏览器会对数据进行缓冲。
二、Buffer类存在的意义
- Buffer 类是随 Node 内核一起发布的核心库。Buffer 库可以存储原始数据,让Node.js 处理二进制数据;
- 每当需要在Node.js 中处理I/O操作中移动的数据时,就有可能使用 Buffer 库。
Buffer类是以字节数组的方式进行存储数据。
三、Buffer类的基本操作
1、 创建Buffer类
Buffer.alloc(size[, fill[, encoding]]):
分配 size 个字节的新 Buffer。 如果 fill 为 undefined,则 Buffer 将以零填充,如果 size 大于 buffer.constants.MAX_LENGTH 或小于 0,则抛出ERR_INVALID_ARG_VALUE。
如果指定了 fill,则分配的 Buffer 将通过调用 buf.fill(fill) 进行初始化。
size
<integer>
新的 Buffer 所需的长度。
fill<string> | <Buffer> |<Uint8Array> | <integer>
用于预填充新 Buffer 的值。默认值: 0。
encoding<string>
如果 fill 是字符串,则这就是它的编码。默认值: 'utf8'。
//创建一个长度为5、且用0x1填满的Buffer
const buf1 = Buffer.alloc(5,1);
//<Buffer 01 01 01 01 01>
const buf2 = Buffer.alloc(5);
console.log(buf2);
//<Buffer 00 00 00 00 00>
const buf3 = Buffer.alloc(5, 'a');
console.log(buf3);
//<Buffer 61 61 61 61 61>
Buffer.from(array):
使用0-255范围内的字节数组array来分配一个新的Buffer。如果array不是一个Array或适用于Buffer.from()变量的其他类型,则抛出TypeError。
//创建一个包含 [0x1, 0x2, 0x3] 的 Buffer。
const buf4 = Buffer.from([1, 2, 3,4,5,6]);
console.log(buf4);
//<Buffer 0x1 0x2 0x3 0x4 0x5 0x6>
const buf5 = Buffer.from([0x42,0x75,0x66,0x66,0x65,0x72])
//若要验证buf5,利用toString()方法即可--返回一个解码过的 string 类型
console.log(buf5.toString());
//Buffer
2、写入缓冲区
buf.write(string[, offset[, length]][, encoding]):
根据 encoding 中的字符编码将 string 写入 buf 的 offset 处。 length 参数是要写入的字节数。 如果 buf 没有足够的空间来容纳整个字符串,则只会写入 string 的一部分。 但是,不会写入部分编码的字符。
string
<string>
要写入 buf 的字符串。
offset<integer>
开始写入 string 之前要跳过的字节数。默认值: 0。
length<integer>
要写入的最大字节数(写入的字节数不会超过buf.length - offset)。默认值: buf.length - offset。
encoding<string>
string 的字符编码。 默认值: ‘utf8’。
let buf = Buffer.alloc(10);
let len = buf.write('hellohello');
console.log(len);//10
//2表示要跳过两位
let len = buf.write('hellohello',4,5)
console.log(len); //5
3、剪裁缓冲区
buf.slice([start[, end]]):
返回新的 Buffer,其引用与原始缓冲区相同的内存,但由 start 和 end 索引进行偏移和裁剪
start 新的 Buffer 将开始的位置。 默认值: 0。
end 新的 Buffer 将结束的位置(不包括在内)。 默认值: buf.length.
let buf = Buffer.from('hellohello');
let buf1 = buf.slice(3,6);
console.log(buf1);//<Buffer 6c 6f 68>
console.log(buf1.toString());//loh
4、将 Buffer 转换为字符串
buf.toString([encoding[, start[, end]]]):
根据 encoding 中指定的字符编码将 buf 解码为字符串。 start 和 end 可以传入仅解码 buf 的子集。如果 encoding 是 ‘utf8’ 并且输入中的字节序列不是有效的 UTF-8,则每个无效字节都将替换为替换字符 U+FFFD。
encoding
<string>
要使用的字符编码。 默认值: ‘utf8’。
start<integer>
开始解码的字节偏移量。默认值: 0。
end<integer>
停止解码的字节偏移量(不包括在内)。 默认值:buf.length.
返回:<string>
const buf1 = Buffer.alloc(26);
for (let i = 0; i < 26; i++) {
// 97 是 'a' 的十进制 ASCII 值。
buf1[i] = i + 97;
}
console.log(buf1.toString('utf8'));
// 打印: abcdefghijklmnopqrstuvwxyz
console.log(buf1.toString('utf8', 0, 5));
// 打印: abcde
const buf2 = Buffer.from('tést');
console.log(buf2.toString('hex'));
// 打印: 74c3a97374
console.log(buf2.toString('utf8', 0, 3));
// 打印: té
console.log(buf2.toString(undefined, 0, 3));
// 打印: té
5、拼接Buffer类
Buffer.concat(list[, totalLength]):
返回新的 Buffer,它是将 list 中的所有 Buffer 实例连接在一起的结果。如果列表没有条目,或者 totalLength 为 0,则返回新的零长度 Buffer。如果未提供totalLength,则从 list 中的 Buffer 实例通过相加其长度来计算。如果提供了 totalLength,则将其强制为无符号整数。 如果 list 中 Buffer 的组合长度超过 totalLength,则结果截断为 totalLength。
list <Buffer[]> | <Uint8Array[]> 要连接的 Buffer 或 Uint8Array 实例的列表。
totalLength<integer>
连接时 list 中 Buffer 实例的总长度。
const buf1 = Buffer.alloc(1);
const buf2 = Buffer.alloc(4);
const buf3 = Buffer.alloc(8);
const totalLength = buf1.length + buf2.length + buf3.length;
console.log(totalLength);
// 打印: 13
const bufA = Buffer.concat([buf1, buf2, buf3], totalLength);
console.log(bufA);
// 打印: <Buffer 00 00 00 00 ...>
console.log(bufA.length);
// 打印: 13
6、检查字符编码名称
Buffer.isEncoding(encoding):
如果 encoding 是支持的字符编码的名称,则返回 true,否则返回 false。
encoding
<string>
要检查的字符编码名称。
console.log(Buffer.isEncoding('utf8'));
// 打印: true
console.log(Buffer.isEncoding('hex'));
// 打印: true
console.log(Buffer.isEncoding('utf/8'));
// 打印: false
console.log(Buffer.isEncoding(''));
// 打印: false
7、将 Buffer 转换为 JSON 对象
buf.toJSON():
返回 buf 的 JSON 格式。 当字符串化 Buffer 实例时,JSON.stringify()
会调用该函数。
const buf = Buffer.from('hellohello');
const json = JSON.stringify(buf);
console.log(json);
//{"type":"Buffer","data":[104,101,108,108,111,104,101,108,108,111]}
JSON.stringify()该方法是转换为json格式的字符串
总结:
1.Buffer类的一些基本操作与数组的一些方法有共通之处,比如slice()方法、concat()方法等,因此我们可以联想记忆;
2.在js中每种编码格式的规则不同,返回Buffer类的长度时,会根据编码格式不同而不同,比如utf-8编码格式中,一个字符代表三个字节,ASCII中一个字符代表一个字节;
3.利用Buffer.from()方法返回的是16进制的结果,而通过Buffer.toJSON方法返回的是10进制的结果。