buffer介绍
- buffer是一段暂时存放输入输出数据的一段内存
- js语言没有二进制数据,在处理tcp和文件流的时候必须要处理二进制。NODEJS提供了一个Buffer类提供对二进制数据的操作。node把二进制转换成十六进制,存入buffer。
- bufferi里每一项都是一个十六进制,表示一个字节。
- Buffer是一个表示固定内存分配的全局对象,是global的属性。
- 特点:放到缓存区中的字节数要提前确定。
- buffer好比一个多为字节元素组成的数组,每一项都是一个字节,可以有效的在js中表示二进制数据
字节
- 单位 b
- 1b = 8bit 1字节=8个二进制位,转换成十进制最大是255
- 1024b = 1k 1024字节=8个位
- 1个utf8编码的汉字 = 3个字节 = 3b
进制表示:0b表示十进制 ;0x表示16进制 ;0开头表示8进制 0377 =>255
buffer创建
- 通过长度创建
//alloc 分配。比较耗费性能,分配的都是干净的内存
let buf = Buffer.alloc(5);//创建一个长度为5的干净的buffer,
console.log(buf) // [00,00,00,00,00]
//allocUnsafe安全分配
let buf1 = Buffer.allocUnsafe(5)//创建一个长度为5,但是不干净的buffer
console.log(buf1) //[03,FF,00,13,00]
复制代码
- 通过数组创建,自动把十进制转换成16进制,存入数组。数组中必须是数字,可以是10进制、16进制 8进制,但是都不能大于255
let buf = Buffer.from([17,18,19,0x11])
console.log(17,18,19,0x11)//<Buffer 11 12 13 11>
复制代码
- 字符串创建
let buf = Buffer.from('欢迎光临')
console.log(buf);
//发现buf的长度是12,buf中存放着12个十六进制,也就是12个字节。
//buffer的长度,就是字节的个数,一个汉字对应3个字节,每个字节都转换为16进制,存入到buffer中
console.log(buf.length);查看buf的长度
复制代码
buffer的常用方法
实例调用
- toString 转字符串,还可以指定编码。
let buf = Buffer.from('欢迎光临');
console.log(buf.toString());//欢迎光临
var buf = Buffer.from('珠');
console.log(buf.toString('base64')); //54+g
复制代码
- fill 填充
// fill 填充
// * @param {Number|String} value (if it's string, the first char code is used) 填充内容
// * @param {Number?} [offset=0] start buffer offset,不传,就从头开始
// * @param {Number?} [end=this.length] end buffer offset,不传就到结尾
let buf1 = Buffer.allocUnsafe(5)//创建一个长度为5,但是不干净的buffer
console.log(buf1) //[03,FF,00,13,00]
buf1.fill(0) 将buf全部重置为0
复制代码
- slice 截取、浅克隆(截取的是内存)。
let buf = Buffer.from([1,2,3,4]);
let newBuf = buf.slice(0,1);//[01]
newBuf[0] = 100; //100除以16,商6余4,所以十六进制 是64; 64=>100 16*6+4
console.log(buf) <64,02,03>
//通过修改新的 newBuf,旧的buf也发生了改变,slice截取的是一段内存。
复制代码
- copy 拷贝,将一个buf拷贝到另一个buf中。要copy哪个,哪个来调用copy
//param:目标buffer、目标buffer开始位置、源开始位置(可省略,省略表示从头开发copy)、源结束位置(可省略,表示copy到结尾);
var buf1 = Buffer.from('欢迎');
var buf2 = Buffer.from('光临');
var buf = Buffer.allocUnsafe(12);//12个字节
buf1.copy(buf,0) //=>buf2.copy(buf,0,0,6)
buf2.copy(buf,6,0,6) // => buf2.copy(buf,6)
console.log(buf)
console.log(buf.toString())//欢迎光临
复制代码
Buffer类调用
- buffer拼接 Buffer.concat([buf1,buf2],totalLength);
//没传totallength,会自动计算新bug的长度;
//传入的totallength已totallen为准,totallength大于总长度,那么会截取buf,降低内存消耗
var buf1 = Buffer.from('欢迎');
var buf2 = Buffer.from('光临');
console.log(Buffer.concat([buf1, buf2]).toString()); //欢迎光临
console.log(Buffer.concat([buf1, buf2],3).toString());//欢
console.log(Buffer.concat([buf1, buf2],4).toString());//欢�
console.log(Buffer.concat([buf1, buf2],100).toString());欢迎光临
//手写concat方法
Buffer.myConcat = function(list,totalLength){
//判断长度,如果传递了用传的,没传自己计算总长度。
if(typeof totalLength == "undefined"){
totalLength = list.reduce((prev,next)=>{
return prev + next.length;
},0)
}
//通过长度创建一个buffer
let B = Buffer.alloc(totalLength);
//循环list,将每一项copy到这个大buffer上,buf.copy
let offset = 0 ;
list.forEach(buf=>{
if(!Buffer.isBuffer(buf)) return new Error('not buffer');
buf.copy(B,offset)
offset += buf.length;
})
//如果长度过长,fill把空闲内容清空,或者财通slice截取有效长度
return B.slice(0,offset)
}
复制代码
- 判断是不是buffer
Buffer.isBuffer(buf1); // true
复制代码
js进行进制转换
- toString(目标进制) 10->2 16->2 10->16 16->8 8->16
(0xff).toString(8) // '377'
(255).toString(2) // "11111111"
(255).toString(16) //"ff" => 255/16 ,商15余16 所以是ff
(255).toString(8) //"377" => 255/8 商31余7
31/8 商3余7
从下往上所以是377
复制代码
- parseInt(被转数,被转数的进制),16->10 2->10 8->10
parseInt("0xff",16) //255 16的0次方 * f(15) + 16的1次方 *f(15)
parseInt("11111111",2) //255 2的0次方*1 + 2的一次方*1 +2的2次方*1+....
parseInt("377",8) //255 =>8的0次方 *7 + 8的一次方*7 + 8的二次方*3
复制代码
- base64编码依靠的就是进制转换
- 汉字转base64: 汉字=> 3个字节的buffer => 16->2进制 => 24bit => 4个字节 =>2->10 =>去可见编码取值
过程:
var buf = Buffer.from('珠');
console.log(buf.toString('base64'));
//把一个汉字的24位,转换成4个字节,每个字节就6位,不足的补0;
console.log(buf); //e7 8f a0
//1.把16转换成2进制 toString
console.log((0xe7).toString(2)); //11100111
console.log((0x8f).toString(2)); //10001111
console.log((0xa0).toString(2)); //10100000
// 11100111 10001111 10100000
// 111001 111000 111110 100000
// 00111001 00111000 00111110 00100000 , 最大就是00111111,转换十进制,最大就是63,不超过64
// 2.将这些纸转换成10,去可见编码中取值;
//parseInt,将指定进制的数 转换成10进制
console.log(parseInt('00111001',2)); //57
console.log(parseInt('00111000',2)); //56
console.log(parseInt('00111110',2)); //62
console.log(parseInt('00100000',2)); //32
//3.去可见编码中取出值为 54+g
let str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
str +="abcdefghijklmnopqrstuvwxyz";
str += "0123456789";
str +='+/';
console.log(str[57]+str[56]+str[62]+str[32])
"珠" => 54+g
复制代码
bse64可见编码
字符串具有不变性
var str1 = "欢迎光临";
str1[0] = 'hello';//改变不了的 因为字符串具有不变性
console.log(str1); //"欢迎光临";
复制代码