概念buffer存储什么?Buffer是一个操作字节的对象。它的底层是一个存储十六进制数的字节数组。varstr='hellobuffer'varbuffer=newBuffer(str,'utf-8')console.log(buffer)//输出为十六进制数。缓冲区的每个元素都是一个两位十六进制数,即每个元素的大小为0-255。因为FX16+FX16^0=255溢出了,怎么办?我们可以直接给buffer的元素赋值varbuffer=newBuffer(10)buffer[0]=300console.log(buffer[0])如果赋值是小数,小数部分会直接丢弃.溢出时,大于255减256直到小于255,小于0加256大于0if(x>255){while(x>255){x=x-256}}if(x<0){x=x+256}补充:~~~~负数在计算机中以补码形式存储,最高位为符号位(0为正,1为负数),除符号位外,其他位取反,最低位取反后加1,如:-1取反前:10000001取反:11111110,最后一位加1:11111111,这样电脑读到的就是255。string和Buffer的转换可以直接转换编码类型包括:ASCII;UTF-8;UTF-16LE/UCS-2;Base64;二进制;十六进制;从js切换到c++更消耗性能。iconv-lite:纯Js实现,效率更高。基本转换varbuffer=newBuffer(str,[enconding])buffer.toString([enconding])分段转换注意同一个codec必须使用相同的encondingvarbuffer=Buffer.write(str,[offset],[length],[enconding])buffer.toString([enconding],[start],[end])库iconv/iconv-lite的使用由于我们常用的GBK和GB2312不在Buffer默认支持的编码列表中,所以需要使用第三方库进行编解码。图书馆无法转换图书馆的内容。总结iconv-litejs实现直接输出乱码。它不需要从c++切换到js。性能更好。iconv调用c++提供忽略或翻译处理。对乱码的处理比较完善。variconv=require('iconv-lite');varbuffer=iconv.encode('床前月光','GBK');varstr=iconv.decode(buffer,'GBK')缓冲区拼接:解决办法把乱码也接收到buffer,直接用加号拼接buffer。输入长字节时,容易产生乱码。varfs=require('fs')varrs=fs.createReadStream('test.md',{highWaterMark:11})vardata=''rs.on('data',function(chunk){data+=chunk})rs.on('end',function(){console.log(data)//输出有乱码,因为一个汉字有3个字节,不能被11整除,第三个字符可以只包含两个字节显示,会出现乱码})正确的拼接方式是用数组存储每次读取的chunk,然后用buffer.concat生成合并后的Buffer对象。varfs=require('fs')variconv=require('iconv-lite');varrs=fs.createReadStream('test.md',{highWaterMark:11})varchunks=[]varsize=0rs。on('data',function(chunk){chunks.push(chunk)size+=chunk.length;})rs.on('end',function(){varbuffer=Buffer.concat(chunks,size)varstr=iconv.decode(buffer,'utf-8')console.log(str)})buffer的性能优势在网络传输中,如果先将传输的对象转换成buffer,可以提高系统性能。对于文件操作,文件本身存储的是二进制数据,所以在不需要改变文件内容的场景下,直接调用Buffer性能是最好的。另外,highWaterMark的值会影响性能。highWaterMark设置过小,会导致读取次数过多。使用)。对于大问题的读取,设置比较大的highWaterMark可以提高性能。
