前言:
这段时间在学习用nodejs做一个微信公众号的后端开发。node真是百闻不如一见,这回见着了,觉得node和浏览器端js差别还是挺明显的(众:你这不废话吗!)。嘿嘿,今天处理一段request数据时,用了一个办法是先把它转成buffer对象,然后再将其重新编码,所以今天就来侃侃Buffer吧!
Buffer是啥?
字面理解一下Buffer(缓冲)对象:
一般编程所说的缓冲区指的是内存缓冲区,这是程序所设置的一块内存区域,用来暂存从其他设备读入的数据或即将写入其他设备的数据.
好,下面我们关心一下node里面的缓冲对象:
对于JavaScript来说,对Unicode编码的数据很容易处理的但是对于二进制数据就没什么处理方法了。但是在一些TCP数据流或者在操作一些文件数据流的时候,字节流的处理方法还是必须的。nodeJS中便出了处理的策略方法~提供了与String类似对等的全局构造函数Buffer(与其说与String对等,还不如说与Array类似但是有些不同方面还是需要注意),全局那么自然就不要每次的require了。Buffer是node中储存二进制数据的中介者。
创建一个Buffer对象!
形式就是地球人都知道的 var xx = new Buffer()嘿嘿嘿.
(啊呸,当然没那么随意!)
(正经脸)
- 方式一: new Buffer(size)
- 方式二: new Buffer(array)
- 方式三: new Buffer(string, 编码方式)
解读: 第一种形式中,size是你想要建立的buffer对象所占的内存的字节个数。第二种形式中,直接传入你想要建立的buffer对象的数组形式,当然数组的每一个元素都是16进制表示的一个字节,第三种方式中,传入一个字符串,然后第二个参数告诉Buffer你字符串的编码方式,它会按照你告诉他的编码方式去拆分这个字符串,把它解码为16进制的字节。
示例:
1 | // 方法一 |
区分Buffer对象和字符串对象
其实没有什么好区分的(毕竟完全不一样啊喂!😂),这里主要是强调一下它们的读写特征。
我们知道,字符串是只读的,比如这样写:
1 | var a = "hello"; |
猜猜a最后长什么样子?答案是a仍然是”hello”而不是”bello”!因为字符串是只读的,一旦你创建了一个字符串,那么它就在那里,然而我们的缓冲对象是灵活的,你改了它,它就会给你变变变,因此,如果我们想基于一个缓冲对象做一些改变,又不想失去这个对象本身,我们最好这么做:
请出伟大的copy方法:
1 | buf.copy(targetBuffer,[targetStart],[sourceStart],[sourceEnd]); |
参数解释:
在Buffer对象的copy方法中,使用四个参数,第一个参数为必须指定的参数,其余三个参数均为可选参数。第一个参数用于指定复制的目标Buffer对象。第二个参数用于指定目标Buffer对象中从第几个字节开始写入数据,参数值为一个小于目标的Buffer对象长度的整数值,默认值为0(从开始处写入数据)。第三个参数用于指定从复制源Buffer对象中获取数据时的开始位置,默认值为0,即从复制源Buffer对象中的第一个字节开始获取数据,第四个参数用于指定从复制源Buffer对象中获取数据时的结束位置,默认值为复制源Buffer对象的长度,即一直获取完毕复制源Buffer对象中的所有剩余数据。
来个栗子:
1 | var b = new Buffer("我喜欢写代码"); |
敲进你的终端里try一下吧!会有新发现的!哈哈~
常用的静态方法
1 | Buffer.isBuffer(obj) |
用于判断obj对象是否是Buffer类型
1 | Buffer.byteLength(string,[encoding]); |
用于计算传入的string的字节长度,encoding是编码方式,默认编码方式是utf8.
1 | Buffer.concat(list,[totalLength]); |
Buffer的连接,用于连接Buffer的数组。我们可以手动分配Buffer对象合并后的Buffer空间大小(参数二),如果Buffer空间不够了,则数据会被截断。
1 | Buffer.isEncoding(encoding); |
encoding是编码格式,如果这个编码格式是有效的,比如”utf8”穿进去,那铁定没问题,但是如果是个别的,比如你写个”xixi”,那你就呵呵吧。。。。。(逃。。。。。)
总结
(咦怎么就总结了??)
哈哈,这当然没完,但是以上都是我感觉中Buffer比较基础和核心的部分,所以我把它们记录下来(严肃脸),因为目前对node的各种对象的api的实践都是有限的,所以只能吐这么墨水出来啦。以后随着学习的推进,会增加更丰富的内容的^^