Node.js 之 Buffer 对象
在对 fs 模块进行介绍时,我们说过读取文件时,默认返回的结果是 Buffer
对象,本篇文章就说说到底什么是 Buffer
。
在前端项目中,如果我们要处理一些文件、图片等二进制内容,可能会用到 Blob
或 ArrayBuffer
对象,可参见 《Vue 大文件上传和断点续传》。而在 node 中,提供了一个全局的类 Buffer
,来处理二进制的数据。一个 Buffer
对象可以看成是一个存储二进制数据的数组,里面的每一项都保存着 8 bit(位) 的,也就是 1 byte(字节) 的二进制。
创建 Buffer 对象
虽说 Buffer
是一个类,但是不推荐直接使用 new Buffer()
的方式创建实例,否则会有警告如下:
Buffer.from()
我们先来看看提示里 Buffer.from()
的使用,它可以传入一个字符串来生成一个 buf
:
const buf = Buffer.from('hello juejin')
console.log(buf)
打印结果如下:
或许有人会问了:说好的 Buffer
对象里每一项保存的是 8 位二进制呢?这看起来咋成了十六进制?这是因为如果每一项都以二进制来展示不方便,所以每 4 位二进制会转换为 1 个十六进制的值,比如 "h",在 utf8 中使用二进制表示就是 "0110 1000",其中 "0110 " 和 "1000" 转为十六进制对应的分别就是 "6" 和 "8"。
使用英文字母时,一个字母对应一个字节,如果传入的字符串是中文,则是 3 个字节对应一个汉字:
打印结果如下:
如果想得到我们能看懂的文本,可以通过 buf.toString()
,但是请注意,如果在生成 buf
时,第 2 个参数 —— 编码格式(默认为 utf8)传入了参数,则在解码时也需要传入相同的编码格式:
否则字符串为中文时可能会出现乱码,比如 utf-16 里所有 unicode 字符对应的码点都用 2 字节保存,所以如果单纯打印 console.log(buf)
得到的结果如下:
Buffer.alloc()
Buffer.alloc()
第 1 个参数用于指定大小,以向操作系统申请一块指定大小的内存空间,比如:
const buf = Buffer.alloc(2) // 2 字节大小的 Buffer
然后可以设置各个字节的内容:
buf[0] = 0x48 // 十六进制
buf[1] = 105 // 十进制,转成十六进制为 0x69
console.log(buf)
console.log(buf.toString())
打印得到的结果如下:
如果想赋值英文字母,可以通过 charCodeAt()
获取 utf-16 代码单元后赋值:
buf[0] = 'H'.charCodeAt()
请注意,虽然表面上我们传入 Buffer.alloc()
的大小为 2
,但事实上 node 并不会真的只向操作系统申请 2 字节大小的内存,而是默认申请 8 * 1024 个字节大小(8kb) 的内存,这样当我们之后再执行比如 Buffer.alloc(12)
时它就判断下之前申请的 8kb 的空间是否用完,若有剩余则直接填充,以避免频繁的申请内存操作,提高性能。
转载自:https://juejin.cn/post/7202127250644598840