多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
目录 (づ ̄ 3 ̄)づ=> [TOC] ## 什么是Buffer Buffer是存放输入输出数据的一段内存,这些数据是一个个**字节**并且以16进制的形式表示。 一个字节就是一个英文字母 一个字节等于8位,256种状态,可以表示 0-255,换算成16进制,就是两位数(16\*16=256) ``` console.log(Buffer.from(['moximoxi'); //<Buffer 6d 6f 78 69 6d 6f 78 69> ``` ## Buffer方法 ### alloc ``` let bf1 = Buffer.alloc(6,11); //第二个参数为填充值,默认为0,第三个为编码 console.log(Buffer.from(['moximoxi'); //<Buffer 6d 6f 78 69 6d 6f 78 69> ### allocUnsafe ### from >[info] Buffer.from(string[, encoding]) **encoding <string> string 的字符编码。 默认: 'utf8'** ``` console.log(Buffer.from('嘻嘻')); // <Buffer e5 98 bb e5 98 bb> ???-> console.log(Buffer.from([17,'moximoxi',19,0x11,200])); // <Buffer 11 00 13 11 c8> //如果from的是一个数组,数组只能放数字,如果有字符串会被替换成0 ``` ### write ``` let bf2 = Buffer.alloc(4); //1.要写的字符串 2.填充的开始索引 3.填充的字节长度 4.编码 bf2.write('嘿嘿',0,3,'utf8');// [x,x,x,0,0,0] ``` ### fill ``` let bf2 = Buffer.alloc(4); //1.填充的值 2.填充的开始索引 3.结束索引 bf2.fill(3,1,3); //[0,3,3,0] ``` ### copy ``` /** * copy 考到哪里 * @param targetBuffer 目标buffer * @param targetStart 目标的开始 * @param sourceStart 源的开始 * @param sourceEnd 源的结束 */ var bf3 = Buffer.from('珠峰'); var bf4 = Buffer.from('培训'); var bf5 = Buffer.allocUnsafe(bf3.length+bf4.length); bf3.copy(bf5,0); //bf3考到bf5 bf4.copy(bf5,6); console.log(bf5.toString()); ``` #### copy实现 ``` /** * copy 实现 * @param targetBuffer * @param targetStart * @param sourceStart * @param sourceEnd */ Buffer.prototype.copy2 = function(targetBuffer,targetStart,sourceStart,sourceEnd=this.length){ for(let i= sourceStart;i<sourceEnd;++i){ targetBuffer[targetStart++] = this[i]; } } ``` ### concat ``` /** * concat 连接buffer * @param arr 要链接的bff数组 * @param [num]申请的空间,不填为arr的buffer空间综合 */ console.log(Buffer.concat([bf3,bf4]).toString()); ``` #### 用copy方法实现concat ``` Buffer.iConcat = function(list,totalLength){ //将list中传入的buffer集合合并后返回 1.先判断是否传入期望合并后的Buffer的总长度,如果没有则将buffer集合的总长度作为返回Buffer的长度 if (totalLength === undefined) { totalLength = list.reduce((prev, next) => prev + next.length, 0); } 2.创建一个Buffer,将其总长度设为totalLength let Bf = Buffer.alloc(totalLength); , offset = 0; 3.利用copy方法用新创建的Buffer来装list中的各个子buffer list.forEach((bf) => { bf.copy(Bf, offset); offset += bf.length; }); 4.如果期望的总长度大于实际Buffer长度决定是截取还是填充多余的位置 5.返回 return Bf.slice(0, offset); } ``` #### 非copy实现 ``` /** * concat 实现 * @param list * @param total * @return {*} */ Buffer.concat = function(list,total=list.reduce((len,item)=>len+item.length,0)){ if(list.length===1){ return list[0]; } let result = Buffer.alloc(total); let index = 0; for(let buf of list){ for(let b of buf){ if(index<total){ result[index++] = b; }else{ //如果设定的总长小于所有子bf的总长会走这里 return result; } } } //如果传入的长度超过所有子bf的总长,以及顺利将所有子bf赋给大bf 会走这里 return result; } ``` ## Buffer字节、机制以及转换 - 一个字节(byte)等于八位(bit),1111 1111(0-255) - 0?? 0开头表示八进制 - 0x?? 0x开头表示十六进制 - 0b?? 0b开头表示二进制 ### Buffer进制转换 > .tostring() ``` //常用来Buffer.from(string)得来的bf进行转换 let bf = Buffer.from('123'); bf.tostring(2); //用二进制进行编码 bf.tostring(8); //用八进制进行编码 //... 依次类推 bt.tostring('base64'); //用base64进行编码 ``` ### base64 base64编码一个字节只有六位,多余的两位用0补上 可见字符有64个a-zA-Z0-9+/ ``` //进制转换 let buf = Buffer.from('珠'); // console.log(buf.toString('base64')); //base64 如果一个汉字有24位(3个字节) 转换成4个字节 每个字节就6位 不足补0 console.log(buf); //1.把16进制转化成2进制 toString() console.log((0xe7).toString(2)); console.log((0x8f).toString(2)); console.log((0xa0).toString(2)); // 00111111=>63 console.log(parseInt('00111001',2)); //标准64只有64个可见字符 // '+/' 'AZaz' '09' console.log(str[57]+str[56]+str[62]+str[32]); ``` ![](https://box.kancloud.cn/d46506ce8b6a660fda52ddd4857cc426_866x653.png) ## Buffer 与 数字 ``` ws.write(123456789) //TYPE ERROR console.log(Buffer.from([1,2,255])); console.log(Buffer.from('123','base64')) console.log(Buffer.from('123','utf8')) let bf = Buffer.alloc(3); bf.writeInt8(123,0); console.log(bf) console.log(bf.readInt8(bf)) console.log(Buffer.from([123])); //--------------------------------- >>> <Buffer 01 02 ff> <Buffer d7 6d> <Buffer 31 32 33> <Buffer 7b 00 00> 123 <Buffer 7b> ``` 区别在于from的必须是一个数组形式,读的时候可以tostring ,writeInt的时候可以只写入一个数字,但读的时候必须配合readInt