最近因为要处理TCP发过来的包,TCP提供的是字节流服务,接收端不知道每次TCP发送端每次发送的数据是多少字节。所以接收端就不能每次都把接收到的数据都按照同样的方式进行处理,假如,我们每次处理156 ,但是每次接收的可能之后100个字节,这样就会造成解析错误。所以我们采取了一个环形Buffer的方式,接收到的数据,都放到缓存环形Buffer中,取得时候,就每次取156个长度的Buffer,进行处理即可。这个过程中,充分学习了Buffer的各种操作,对其原理进行了了解。
1.创建Buffer的方式:
Buffer 类是一个全局变量类型,用来直接处理2进制数据的。 它能够使用多种方式构建。
new Buffer(8)
分配一个大小为8字节的buffer,长度为8
var testbuffer = new Buffer(10);
console.log(testbuffer.length);
输出:10
这时缓冲区的数据并没有被初始化为0,而是随机数据。
new Buffer(str ,[encoding])
分配一个新的 buffer ,其中包含着给定的 str字符串. encoding 编码方式默认是:'utf8'.它的长度要根据存入的str来定,其中一个中文字符(标点也是)占三个字节。例如:
var testbuffer = new Buffer("test测试");
console.log(testbuffer.length);
打印输出:10
new Buffer(Buf)
复制Buf到一个新的Buffer实例中
var testbuffer = new Buffer("test测试");
console.log(testbuffer.length);
console.log(testbuffer.toString());
var testbuffer1 = new Buffer(testbuffer);
console.log(testbuffer1.length);
console.log(testbuffer1.toString());
输出:
10
test测试
10
test测试
new Buffer(array);
创建一个Buffer,用一个八位字节的数组。
var testbuffer = new Buffer([0x74,0x65,0x73,0x74]);
console.log(testbuffer.length);
console.log(testbuffer.toString());
输出:
4
test
2.设置Buffer内容
buf.write(string, [offset], [length], [encoding])
string:要写入的字符串
offset:偏移量,默认为0
length:长度,默认为字符串的长度
encoding:编码,默认为utf-8
var testbuffer = new Buffer(10);
testbuffer.write('test',0);
testbuffer.write('buffer',4);
console.log(testbuffer.toString());
输出:
Testbuffer
var testbuffer = new Buffer('test测试');
testbuffer.write('test');
testbuffer.write('buffer',4);
console.log(testbuffer.toString());
输出:
testbuffer
要把数字以大小端的方式写入buffer,采用buffer的api,他有很多种这样的api,我们来以buf.writeInt32LE(value, offset, [noAssert])为例
value Number类型
offset Number类型
noAssert Boolean类型, 可选参数, 默认: false
介绍这个API之前,还是要先介绍下大小端读取和写入方式,
比如现在要存入16843008,其二进制为00000001 00000001 00000001 00000000
如果以小端的方式存的话,地址为4001,4002,4003,4004
那么他们对应方式为:
2001 | 2002 | 2003 | 2004 |
00000000 | 00000001 | 00000001 | 00000001 |
也就是低地址存放,值的低位,高地址存放值的高位
这种存储方式最适合人的思维,
如果以大端来存的话,对应方式为:
2001 | 2002 | 2003 | 2004 |
00000001 | 00000001 | 00000001 | 00000000 |
也就是低地址存放,值的高位,高地址存放值的低位
这种方式最适合人的感官感觉 一一对应
怎么放的,怎么读就可以了,比如以小端读取小端方式存储的时候,读取到的数据是 00000001 00000001 00000001 00000000
而读取到大端方式存储的时候,读取到的数据是:
00000000 00000001 00000001 00000001。读取数据错误
那么,对于buf.writeInt32LE(value, offset, [noAssert])就不用多做介绍了,他对应的读方式是buf.readInt32LE(value, offset, [noAssert]),还有很多类似的方式,请看官方API。
3.解码缓冲区
默认的buffer都是以utf-8来编码的,他支持的编码格式有:ascii,utf8,base64,binary(弃用),hex(把每个byte编码成2个十六进制字符)
buf.toString([encoding], [start], [end])
采用这种方式来进行解码
如果设置解码方式,默认为utf-8。
4.Buffer的连接和复制
复制buf.copy(targetBuffer, [targetStart], [sourceStart], [sourceEnd])
也就是把buf中的数据,拷贝到targetBuffer的相应位置。(sourceStart,sourceEnd 不写时,默认复制整个buff)。
var test1 = new Buffer('1234');
var test2 = new Buffer(4);
var test3 = new Buffer('testbuffer');
test1.copy(test2,0)
console.log(test2.toString());
test1.copy(test2,0,2,4)
console.log(test2.toString());
test1.copy(test3,0,2,4);
console.log(test3.toString());
test1.copy(test3,6,2,4);
console.log(test3.toString());
输出:
1234
3434
34stbuffer
34stbu34er
连接Buffer.concat(list, [totalLength])这是个类方法:
list {Array}数组类型,Buffer数组,用于被连接。
totalLength {Number}类型,这里的大小是指所传入的数组,所占用的比特长度,不是数组的长度。如果没有设置这项参数,会进行计算这个值,但是最好还是设置一下,要不然会额外增加运算,影响性能。
此方法返回一个buffer ,由数组中的buffer连接组成的buffer。
如果totalLength设置的小于所占用的长度,那么将会被分隔。
var test1 = new Buffer('test');
var test2 = new Buffer('Buffer测试');
var test3 = Buffer.concat([test1,test2],16);
console.log(test3.toString());
输出:
testBuffer测试
如果设置totalLength为10 那么输出为testBuffer
其中一个中文字符为3个字节。
5.Buffer.byteLength(string, [encoding])
console.log(Buffer.byteLength('Buffer测试', 'ascii'));
输出:12
console.log(Buffer.byteLength('Buffer测试', 'utf-8'));
输出:8
这个方法计算出不同编码,所占用的byte字节。
6. buf.slice([start], [end])
返回一个新的buffer,这个buffer将会和老的buffer引用相同的内存地址,负的索引是从buffer尾部开始计算的。
var test = new Buffer('Buffer测试');
console.log(test.slice(0,9).toString());
console.log(test.slice(0,-3).toString());
输出:
Buffer测
Buffer测
7. buf[index]
获取或者设置在指定index索引位置的8位字节。这个值是指单个字节,范围为16进制的0x00 到0xFF,或者0 到255。
var test = new Buffer(4);
test[0]='0x54';
test[1]='0x45';
test[2]='0x53';
test[3]='0x54';
console.log(test.toString());
输出:TEST
以上就是Buffer的各种操作,就介绍到这里,后面会深入buffer写,看buff而到底是个什么玩意!