Buffer
Buffer 和二进制
我们会发现,对于前端开发来说,通常很少会和二进制直接打交道
,但是对于服务器端为了做很多的功能,我们必须直接去操作其二进制的数据
;
所以 Node 为了可以方便开发者完成更多功能,提供给了我们一个类 Buffer,并且它是全局的。
我们前面说过,Buffer 中存储的是二进制数据,那么到底是如何存储呢?
- 我们可以将 Buffer 看成是一个存储二进制的数组;
- 这个数组中的
每一项
,可以保存 8 位二进制
: 0000 0000
为什么是 8 位呢?
- 在计算机中,
很少的情况我们会直接操作一位二进制
,因为一位二进制存储的数据是非常有限的
; - 所以通常会
将 8 位合在一起作为一个单元
,这个单元称之为一个字节(byte)
; 也就是说 1byte = 8bit
,1kb=1024byte,1M=1024kb;- 比如很多编程语言中的
int 类型是 4 个字节
,long 类型时 8 个字节
; - 比如
TCP 传输的是字节流
,在写入和读取时都需要说明字节的个数
; - 比如
RGB 的值分别都是 255
,所以本质上在计算机中都是用一个字节存储的
;
Buffer 和字符串
Buffer 相当于是一个字节的数组,数组中的每一项对应一个字节的大小:
如果我们希望将一个字符串放入到 Buffer 中,是怎么样的过程呢?
它是怎么样的过程呢?
如果是中文呢?
默认编码:utf-8
如果编码和解码不同:
Buffer.alloc
来看一下 Buffer.alloc:
- 我们会发现创建了一个 8 位长度的 Buffer,里面所有的数据默认为 00;
我们也可以对其进行操作
Buffer 和文件读取
文本文件的读取
图片文件的读取
Buffer 的创建过程
事实上我们创建 Buffer 时,并不会频繁的向操作系统申请内存,它会默认先申请一个 8 * 1024 个字节大小的内存,也就是 8kb
Buffer.from 源码
假如我们调用 Buffer.from 申请 Buffer:
- 这里我们以从字符串创建为例
- node/lib/buffer.js:290 行
fromString 的源码
fromStringFast
接着我们查看 fromStringFast:
- 这里做的事情是判断剩余的长度是否还足够填充这个字符串;
- 如果不足够,那么就要通过 createPool 创建新的空间;
- 如果够就直接使用,但是之后要进行 poolOffset 的偏移变化;
- node/lib/buffer.js:428 行