什么是Buffer?
- 缓冲区Buffer是暂时存放输入输出数据的一段内存。
- Buffer是十六进制。
- JS语言没有二进制数据类型,而在处理TCP和文件流的时候,必须要处理二进制数据。所以,其实我们的node是把数据从二进制转换成了十六进制
- NodeJS提供了一个Buffer对象来提供对二进制数据的操作
- Buffer是一个表示固定内存分配的全局对象,也就是说要放到缓存区中的字节要提前确定
- Buffer好比由一个多位字节元素组成的数组,可以有效地在javascript中表示二进制数据
什么是字节
- 1字节 = 8位
- 1k = 1024字节
- 1个汉字(utf8下) = 3字节 = 24位
- 1个字节转化成十进制是255(因为一个字节8位,每个位都是1的时候,转成十进制是255)
- 1个字节转换成十六进制是ff
定义Buffer的方式
- 一定要先定义好大小
- buffer是16进制的
- 定义的方式
-
通过长度定义buffer
- 注意:下面的alloc的中文意思是“分配”
var buffer = Buffer.alloc(6);//长度为6个字节的buffer,先清空内存,再开辟6个字节的buffer,这种方法比较耗性能 var buffer = Buffer.allocUnsafe(6);//不安全的,上一次内存不清空,直接开辟6个字节的buffer console.log(buffer); console.log(buffer.length);//6
-
通过数组转换成buffer
//将一个数组转换成buffer var buffer = Buffer.from([1,2,3,16,255]); console.log(buffer);//<Buffer 01 02 03 10 ff>,其实就是把上面每个元素转换成十六进制 //注意:数组每个元素最大是255,转换成buffer(16进制)是ff,如果越界,就会对255取模,比如256,则转成buffer就是01 //如果是字符串,也不行,会转成00 console.log(buffer.length);//5
-
通过字符串转换成buffer
//将一个字符串转换成buffer var buffer = Buffer.from('壮壮小伙'); console.log(buffer);//<Buffer e5 a3 ae e5 a3 ae e5 b0 8f e4 bc 99> 一个汉字,三个字节,所以总共有12个16进制 console.log(buffer.length);//12
-
注意,转换成buffer后,length就是buffer的长度了
- buffer的其他方法 -
buffer.fill方法,填充buffer中的内容
//fill方法 var buffer = Buffer.allocUnsafe(10); buffer.fill(0xff); console.log(buffer);//<Buffer ff ff ff ff ff ff ff ff ff ff> 填充的是16进制,那就是16进制 buffer.fill(23); console.log(buffer);//<Buffer 17 17 17 17 17 17 17 17 17 17> 填充10进制,转换成16进制
-
buffer.toString()方法,将buffer转化成字符串
var buffer = Buffer.from('壮壮小伙'); console.log(buffer.toString());//'壮壮小伙'
-
buffer.slice方法,截取想要的buffer
- 与数组一样,浅拷贝,存在引用关系
-
buffer.copy方法,拷贝buffer
- 重点,常用
- 语法:源Buffer.copy(目标Buffer,目标起始,源起始,源结束);
- 其中结束为止不包括源结束,跟slice(1,2)一样,不包括2
- 原理:先开辟大小,然后一个个拷贝进新开辟的Buffer
var zz1 = Buffer.from('壮壮'); var zz2 = Buffer.from('小伙'); //Buffer不能改变大小,不能push,但可以如下: //先定义大小 var zz = Buffer.allocUnsafe(12);//1个汉字三个字节 //拷贝buffer zz1.copy(zz,0);//参数有四个,分别为:目标Buffer,目标起始,源起始,源结束(不包括) zz2.copy(zz,6); console.log(zz.toString());//'壮壮小伙'
-
Buffer.concat方法,buffer的拼接方法
- 重点,常用
//concat 链接buffer var zz = Buffer.concat([zz1,zz2]);//两个参数,分别为:list(数组),totalLength console.log(zz.toString());//'壮壮小伙'
- 自己手写一个Buffer.concat方法
Buffer.concat = function(list,totalLength){ //1. 判断长度是否传递,如果传递了用传的,没传自己算一个总长度 //2. 通过长度创建一个这么大的buffer,使用Buffer.alloc(长度) //3. 再循环list,将每一项拷贝到这个大buffer上,使用buffer.copy //4. 如果长度过长,可以用fill将过长的部分填充为空,或者可以使用slice截取有效长度 //5. 返回一个新buffer //1 if(typeof totalLength === 'undefined'){ totalLength = list.reduce((prev,next) => prev + next.length,0); } //2 let buffer = Buffer.alloc(totalLength); //3 let offset = 0; list.forEach(buff => { //判断是否为buffer if(!Buffer.isBuffer(buff)){ return throw error('not buffer'); } buff.copy(buffer,offset); offset += buff.length; }) //4 return buffer.slice(0,offset); }
-
Buffer.isBuffer,判断是否是buffer类型
- Buffer.isBuffer(buff),返回boolean
-
自己手写一个Buffer.concat方法
···js
Buffer.concat = function(list,totalLength){
//1. 判断长度是否传递,如果传递了用传的,没传自己算一个总长度
//2. 通过长度创建一个这么大的buffer,使用Buffer.alloc(长度)
//3. 再循环list,将每一项拷贝到这个大buffer上,使用buffer.copy
//4. 如果长度过长,可以用fill将过长的部分填充为空,或者可以使用slice截取有效长度
//5. 返回一个新buffer
//1
if(typeof totalLength === 'undefined'){
totalLength = list.reduce((prev,next) => prev + next.length,0);
}
//2
let buffer = Buffer.alloc(totalLength);
//3
let offset = 0;
list.forEach(buff => {
if(!Buffer.isBuffer(buff)){
return throw error('not buffer');
}
buff.copy(buffer,offset);
offset += buff.length;
})
//4
return buffer.slice(0,offset);
}
···