天天看点

Nodejs进阶:核心模块Buffer常用API使用总结

buffer是node的核心模块,开发者可以利用它来处理二进制数据,比如文件流的读写、网络请求数据的处理等。

buffer的api非常多,本文仅挑选 比较常用/容易理解 的api进行讲解,包括buffer实例的创建、比较、连接、拷贝、查找、遍历、类型转换、截取、编码转换等。

new buffer(array)

buffer.alloc(length)

buffer.allocunsafe(length)

buffer.from(array)

验证下:

例子一:buffer.from(array)

例子二:buffer.from(string[, encoding])

通过string创建buffer,跟将buffer转成字符串时,记得编码保持一致,不然会出现乱码,如下所示。

对乱码的分析如下:

例子三:buffer.from(buffer)

创建新的buffer实例,并将buffer的数据拷贝到新的实例子中去。

判断两个buffer实例存储的数据是否相同,如果是,返回true,否则返回false。

同样是对两个buffer实例进行比较,不同的是:

可以指定特定比较的范围(通过start、end指定)

返回值为整数,达标buf、target的大小关系

假设返回值为

<code>0</code>:buf、target大小相同。

<code>1</code>:buf大于target,也就是说buf应该排在target之后。

<code>-1</code>:buf小于target,也就是说buf应该排在target之前。

看例子,官方的例子挺好的,直接贴一下:

跟 <code>buf.compare(target)</code> 大同小异,一般用于排序。直接贴官方例子:

这里稍微研究下buffer.from(array)。下面是官方文档对api的说明,也就是说,每个array的元素对应1个字节(8位),取值从0到255。

allocates a new buffer using an array of octets.

首先看下,传入的元素为数字的场景。下面分别是10进制、8进制、16进制,跟预期中的结果一致。

再看下,传入的元素为字符串的场景。

<code>0</code>开头的字符串,在parseint('062')时,可以解释为62,也可以解释为50(八进制),这里看到采用了第一种解释。

字符串的场景,跟parseint()有没有关系,暂未深入探究,只是这样猜想。todo(找时间研究下)

感兴趣的同学自行探究。

一开始不自觉的会将<code>buffer.from('1')[0]</code>跟<code>"1"</code>划等号,其实<code>"1"</code>对应的编码是49。

这样对比就知道了,编码为1的是个控制字符,表示 start of heading。

备注:个人觉得<code>totallength</code>这个参数挺多余的,从官方文档来看,是处于性能提升的角度考虑。不过内部实现也只是遍历list,将length累加得到totallength,从这点来看,性能优化是几乎可以忽略不计的。

除了上面提到的性能优化,totallength还有两点需要注意。假设list里面所有buffer的长度累加和为length

totallength &gt; length:返回长度为totallength的buffer实例,超出长度的部分填充0。

totallength &lt; length:返回长度为totallength的buffer实例,后面部分舍弃。

使用比较简单,如果忽略后面三个参数,那就是将buf的数据拷贝到target里去,如下所示:

另外三个参数比较直观,直接看官方例子

跟数组的查找差不多,需要注意的是,value可能是string、buffer、integer中的任意类型。

string:如果是字符串,那么encoding就是其对应的编码,默认是utf8。

buffer:如果是buffer实例,那么会将value中的完整数据,跟buf进行对比。

integer:如果是数字,那么value会被当做无符号的8位整数,取值范围是0到255。

另外,可以通过<code>byteoffset</code>来指定起始查找位置。

直接上代码,官方例子妥妥的,耐心看完它基本就理解得差不多了。

将sring写入buf实例,同时返回写入的字节数。

参数如下:

string:写入的字符串。

offset:从buf的第几位开始写入,默认是0。

length:写入多少个字节,默认是 buf.length - offset。

encoding:字符串的编码,默认是utf8。

看个简单例子

用<code>value</code>填充buf,常用于初始化buf。参数说明如下:

value:用来填充的内容,可以是buffer、string或integer。

offset:从第几位开始填充,默认是0。

end:停止填充的位置,默认是 buf.length。

encoding:如果<code>value</code>是string,那么为<code>value</code>的编码,默认是utf8。

例子:

把buf解码成字符串,用法比较直观,看例子

用于对<code>buf</code>进行<code>for...of</code>遍历,直接看例子。

用于截取buf,并返回一个新的buffer实例。需要注意的是,这里返回的buffer实例,指向的仍然是buf的内存地址,所以对新buffer实例的修改,也会影响到buf。

创建、拷贝、截取、转换、查找

buffer、arraybuffer、dataview、typedarray

buffer vs 编码

buffer.from()、buffer.alloc()、buffer.alocunsafe()

buffer vs typedarray

关于buffer内存空间的动态分配

instances of the buffer class are similar to arrays of integers but correspond to fixed-sized, raw memory allocations outside the v8 heap. the size of the buffer is established when it is created and cannot be resized.

unicode对照表

<a href="https://unicode-table.com/cn/#control-character">https://unicode-table.com/cn/#control-character</a>

字符编码笔记:ascii,unicode和utf-8

<a href="http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html">http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html</a>

继续阅读