Buffer作为nodejs中的一个重要概念和功能,为开发者提供了操作二进制的能力。本文记录几个问题加深对Buffer的理解和使用:如何理解buffer如何申请堆外内存如何计算字节长度如何计算字节长度如何转换字符编码理解共享内存和复制内存?关注公众号《心谭博客》/?查看原文:xxoo521.com/欢迎交流指正缓冲区(buffer)缓冲区是nodejs的核心API,为我们提供了处理二进制数据流的功能Buffer的使用和ES2017的Uint8Array很像,但是由于node的特性,提供了更深层次的API,Uint8Array字面意思是:一个8位无符号整数的数组,一个字节就是8bit,字节表示也是由两个十六进制(4bit)数组成constbuf=Buffer.alloc(1);console.log(buf);//output:如何申请堆外内存Buffer可以跳出nodejs的limit关于堆内内存的大小,nodejs12提供了4个API来申请堆外内存:Buffer.from()Buffer.alloc(size[,fill[,encoding]])Buffer.allocUnsafe(size)Buffer.allocUnsafeSlow(size)Buffer.allocvsBuffer.allocUnsafe申请内存时,这块内存之前可能存储过其他数据,如果不清除原有数据,会存在数据泄露的安全风险;如果清除了原始数据,速度会变慢。使用哪种方法取决于实际情况。Buffer.alloc:申请一块指定大小的内存,并清空原来的数据,默认填充0。Buffer.allocUnsafe:申请一块指定大小的内存,但不清除原来的数据,速度更快。根据提供的API,你可以手动实现一个alloc:functionpollifyAlloc(size,fill=0,encoding="utf8"){constbuf=Buffer.allocUnsafe(size);buf.fill(填充,0,大小,编码);returnbuf;}Buffer.allocUnsafevsBuffer.allocUnsafeSlow可以命名为from直接看效果,Buffer.allocUnsafeSlow比较慢。因为在使用Buffer.allocUnsafe创建一个新的Buffer实例时,如果要分配的内存小于4KB,就会从一个预先分配的Buffer中切掉。这可以防止垃圾收集机制因创建过多的独立缓冲区而不堪重负。这种方法通过消除跟踪和清理的需要来提高性能和内存使用。如何计算字节长度使用Buffer,可以得到数据的实际字节数。比如一个汉字,字符长度为1。但是因为是utf8编码的汉字,所以占用了3个字节。直接使用Buffer.byteLength()获取字符串指定编码的字节长度:conststr="本文原文地址:xxoo521.com";console.log(Buffer.byteLength(str,"utf8"));//输出:31console.log(str.length);//output:19你也可以直接访问Buffer实例的length属性(不推荐):console.log(Buffer.from(str,"utf8").length);//output:31如何转换字符编码目前Nodejs支持的编码格式有:ascii,utf8,utf16le,ucs2,base64,latin1,binary,hex。其他编码需要借助三方库来完成。下面是Buffer.from()和buf.toString()封装的nodejs平台代码转换函数:从);returnbuf.toString(to);}//输出:5Y6f5paH5Zyw5Z2AOiB4eG9vNTIxLmNvbQ==console.log(trans("原地址:xxoo521.com","utf8","base64"));共享内存和拷贝在生成Buffer实例和操作二进制数据时,一定要注意接口是基于共享内存还是基于拷贝底层内存。比如生成Buffer实例的from(),对于不同类型的参数,nodejs的底层行为是不同的。更直观的解释请看下面两段代码。代码1:constbuf1=Buffer.from("buffer");constbuf2=Buffer.from(buf1);//将参数中buffer的数据复制到新实例buf1[0]++;console.log(buf1.toString());//输出:bufferconsole.log(buf2.toString());//输出:缓冲区代码2:constarr=newUint8Array(1);arr[0]=97;constbuf1=Buffer.from(arr.buffer);console.log(buf1.toString());//输出:aarr[0]=98;console.log(buf1.toString());//output:第二段代码中的b,传给Buffer.from的参数类型是arrayBuffer。所以Buffer.from只是创建视图,而不是复制底层内存。buf1和arr的内存是共享的。在操作Buffer的过程中,需要特别注意共享和复制的区别,错误很难排查。参考链接Buffer文档MDNUint8Array如何在Node.js中使用Buffers想更好的了解Node.js中的Buffer吗?看看这篇关于Node.js中Buffer的介绍,专注于前端和算法分享的系列干货,欢迎关注(???)