node buffer

Buffer

格式

Buffer对象类似于数组,他的元素为16进制的两位数,即0到255的数􏳠。在 UTF-8编􏰓码下􏳃中文占3个􏳜􏳝元素,字母和半角符号占1个􏳜􏳝。

理解buffer

流在每次传输过程中,有一个数据量的问题。因此当数据到达的时间比数据理出的时间快的时候,这个时候我们处理数据就需要等待了。如果处理数据的时间比到达的时间快,这一时刻仅仅到达了一小部分数据,那这小部分数据需要等待剩下的数据填满,然后再送过去统一处理。

这个”等待区域”就是buffer! 它是你电脑上的一个很小的物理地址,一般在RAM中,在这里数据暂时的存储、等待,最后在流(stream)中,发送过去并处理。

举例:

我们可以把整个流和buffer的配合过程看做等车,客车在没有装满乘客前是不会发车的,或者在特定的时刻才会发车。乘客(数据)可能在不同的时间,人流量大小也会有所不同。早到的乘客都必须等待,直到公车接到指令可以发车。

当乘客到站,发现公车已经装满,或者已经开走,他就必须等待下一班车次。这个等待的区域就是Node中的Buffer。

Node.js不能控制数据什么时候传输过来,传输速度,就好像公交车站无法控制人流量一样。他只能决定什么时候发送数据。如果时间还不到,那么Node就会把数据放入buffer中,一个在RAM中的地址,直到把他们发送出去进行处理。

作用

用于直接处理二进制数据

创建一个buffer Buffer.alloc(size,[fill,encoding])

size:定义长度(定义后不可变)

fill:填充

encoding:编码类型

1
2
3
4
5
6
var buf = Buffer.alloc(9,"你好","utf-8")
console.log(buf.toString()) // "你好你", 一个汉字占3个长度。


var buf = Buffer.alloc(8,"你好","utf-8")
console.log(buf.toString()) // "你好�", buffer长度为8会出现乱码。

Buffer.from(array)

返回一个新的 Buffer,其中包含提供的八位字节数组的副本。

for … of 、buf.values()、buf.keys()、和 buf.entries() 方法也可用于创建迭代器。

1
2
3
4
5
let b = Buffer.from([1, 3, 4])
console.log(b) // <Buffer 01 03 04>
for(let a of b) {
console.log(a) // 1 , 3, 4
}

Buffer 内存分配

  • Buffer对象的内存分配,不是在V8堆内存中,是在Node的C++􏱠􏱄层面实现内存的申请。

  • node已8k为界限区分大对象还是小对象。

乱码问题

在这个例子里,我们出现了乱码,很显然这不是我问想要的结果。

1
2
3

var buf = Buffer.alloc(8,"你好","utf-8")
console.log(buf.toString()) // "你好�", buffer长度为8会出现乱码。

1、 设置编码方式

1
2
3
4
5
6
7
8
9
10
11
12
13

var fs = require('fs');
var rs = fs.createReadStream('text.md', {highWaterMark: 11});
// 设置编码方式,解决文件读取乱码
rs.setEncoding('utf8');
var data = '';
// data事件的参数返回的buffer,当指定buffer大小时,
rs.on("data", function (chunk){
data += chunk;
});
rs.on("end", function () {
console.log(data);
});

调用setEncoding()时,可读流对象在内部设置了一个decoder对象。每次data事件都通过该decoder对象进行Buffer到字符串的解码。decoder来自于string_decoder模块StringDecoder的实例对象,知道宽字节字符串在UTF-8编码下是以3个字节方式存储的。能够将拆开的字节组合并正确输出。

但是并不是万能的。可以处理UTF-8、Base64、UCS-2/UTF-16LE这3类编码。

2、拼接buffer

  • 记录所有buffer的总长度。

  • 用数组记录所有buffer,然后调用Buffer.concat(chunks, size);

1
2
3
4
5
6
7
8
9
10
11
12
13
var fs = require('fs');
var res = fs.createReadStream('text.md', {highWaterMark: 11});
var chunks = [];
var size = 0;
res.on('data', function (chunk) {
chunks.push(chunk);
size += chunk.length;
});
res.on('end', function () {
var buf = Buffer.concat(chunks, size);
var str = buf.toString('utf-8')
console.log(str);
});
返回
顶部