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); //"欢迎光临";
- 复制代码