Node中的buffer模块,这一篇足够了解了

217 阅读3分钟

本质

关于Node中的buffer模块,官方描述是缓冲区。其实你如果去看他的源码的话会发现,buffer就是一个Uint8Array的子类。得到这个结论的话,通俗的来讲buffer就是为了方便我们去操作ArrayBuffer的一个公共类库,跟类型化数组一个概念,只不过比类型化数组更方便。官方文档传送门点击这里

二进制数据在内存中的存储读取

1、存储

我们学习buffer之前,我们需要先搞懂一个问题:二进制数据在内存中是如何存储的?(在这里我们用一行代码一张图的方式来学习。话不多说,直接上代码!!!)

  • 例子

    const ab = new ArrayBuffer(2)
    

    上面代码表述的是:我们向内存申请2个字节的空间,一个字节等于8位,所以总共16位。如下图(一个方格表示一位):

    未命名文件.png

    继续往下走...

    //接上面代码
    const ua = new Uint8Array(ab);
    ua[0] = 10;
    ua[1] = 25;
    

    因为ArrayBuffer是只读的,所以我们必须使用类型化数组或者DataView来操作ArrayBuffer。在上述代码中:我们给ArrayBuffer中第一个字节存储10(对应二进制1010)、第二个字节存储25(对应二进制11001),并且是由低位到高位存储,空位用0填充,最后得到的结果如下图所示:

    未命名文件 (1).png

2、读取

接下来就是我们的主角buffer登场!!!

//接上面代码
const ab = new ArrayBuffer(2)
const ua = new Uint8Array(ab);
ua[0] = 10;
ua[1] = 25;
const buf = Buffer.from(ua);
buf.readInt8(1)//25

这个例子就是读取第二个字节存储的数据,结果返回25。那么接下来再看另外俩个api:

2.1、buf.readUint16BE(按照16位无符号整数进行读取----大端序)

我们先看一下用buf.readUint16BE去读结果是什么?结果如下:

//接上面代码
buf.readInt16BE(0)//2585

返回的结果是2585,接下来看一下它的读取过程。如下图:

未命名文件 (7).png

小提示:2585的二进制是101000011001

2.2、buf.readUint16LE(按照16位无符号整数进行读取----小端序)

老规矩,我们先看一下用buf.readUint16E去读结果是什么?结果如下:

//接上面代码
buf.readInt16LE(0)//6410

返回的结果是6410,接下来看一下它的读取过程。如下图:

未命名文件 (8).png

小提示:6410的二进制是 1100100001010

2.3、BE与LE对比

未命名文件 (6).png 总结一下:就读取顺序来说其实BE更符合人类的阅读习惯(从左往右)LE更符合计算机的阅读习惯(从右往左)

拓展

  • new Uint8Array() 单位是1个字节,也就是8位(存储0~255)
  • new Uint16Array() 单位是2个字节,也就是16位(存储0~65535)
  • new Uint32Array() 单位是4个字节,也就是32位(存储0~4294967295)
  • new Uint64Array() 单位是4个字节,也就是32位(存储0~18446744073709551615)

  • new Int8Array() 单位是1个字节,也就是8位(存储-128 ~ 127)
  • new Int16Array() 单位是2个字节,也就是16位(存储-32768 ~ 32767)
  • new Int32Array() 单位是4个字节,也就是32位(存储-2147483648 ~ 2147483647)
  • new Int64Array() 单位是4个字节,也就是32位(存储-9223372036854775808 ~ 9223372036854775807)