node之buffer

Buffer

对于一个前端攻城狮,如果你想学习 nodejs ,在这条路上,buffer 将是一个困扰你的玩意,因为在操作 buffer 时,会存在各种各样的编码问题。这在你以前的前端工作中是没有的或者是很少见的,今天我们就来巴拉巴拉 Buffer 这个玩意,不求彻底搞懂,只求搞清楚他是干嘛的,应该怎么用。

1.1 Buffer 结构 

Buffer 是一个像 Array 的对象,但它主要是用来操作字节的。

1.2 Buffer 对象

Buffer 类似于数组,他的每个元素是由两个 16 进制的数字组成,即 0 到 255 的数值。下面是一个简单的代码演示:
  
var str = "我的世界hello";
var buf = new Buffer(str,"utf-8");
console.log(buf);
结果:<Buffer e6 88 91 e7 9a 84 e4 b8 96 e7 95 8c 68 65 6c 6c 6f>

可以看到,不同编码的字符串占用的元素个数各不相同,上面代码中的中文在 UTF-8 编码下占 3 个元素,字母占用了 1 个元素。
Buffer 受 Array 的影响很大,可以访问他的 length 属性,也可以通过下标访问元素,在构造对象时也十分相似,看代码:
var buf = new Buffer(100);
console.log(buf.length) // 100

上述代码分配了长100 字节的 Buffer 。这里就可以通过下标访问 Buffer 中的元素:

console.log(buf[20]);

这里打印得到的结果是不确定的,他是一个 0 到 255 的随机数。
        同样的,我们也可以通过下标对其进行赋值:
buf[10] = 100;
console.log(buf[10]) // 100

这里还有一个有趣的情况,当你给 buf 元素赋的值不在 0 到 255 之间或者给他个小数的值呢?如果是这种情况, Buffer 会自己做简单的处理,规则如下:
  •  当你的赋值小于 0 时,就将该值逐次加 256 ,直到值是一个 0 到 255 之间的整数。
  •  如果值大于 255 时,就将该值逐次减 256, 直到值是一个 0 到 255 之间的整数。
  •  如果是小数,则舍弃掉小数部分,只保留整数部分

1.3 Buffer 内存分配

简单的说,Buffer 采用的是一种内存的动态管理机制。也就是说,他会预先就设定好一块固定大小的内存区域(叫做 slab)。这个区域存在这三种状态:
  • full:完全分配状态(全部使用)
  • partial :部分分配状态
  • empty: 没有分配状态 (没有使用)
当我们需要一个 Buffer 对象时,我们可以直接在创建时就指定大小:
new Buffer(size);
  Node 以 8 KB 为界限来区分 Buffer 是大对象还是小对象:
      Buffer.poolSize = 8*1024

这个 8KB 就是预先分配的固定内存的大小,在我们使用时,会以它作为单元单位进行内存分配。(这里需要说明一下,只要你在创建的时候设置了Buffer 的大小,那么你就不能再改变他的大小)
1. 分配小 Buffer 对象
如果指定的 Buffer 的大小小于 8KB,Node 会按照小对象的方式进行分配。Buffer 的分配过程重要是使用一个局部变量 pool 作为中间对象处,处于分配状态的内存单元会指向他。以下是分配一个全新的slab 单元的操作,他将会申请新的 SlowBuffer 对象指向它:

var pool;

function allocPool(){
    pool = new SlowBuffer(Buffer.poolSize);
    pool.used = 0;
}
然后将创建的 Buffer 对象一个一个的放进这个创建的小 Buffer中,直到他处于full 状态才会继续创建新的slab单元。如果第二次创建的Buffer对象比当前这个 slab 时,就不会继续在这个pool中储存,会重新的分配一个 slab,这样子原来的slab的剩余空间就被浪费掉了。
2.分配大 Buffer 对象
        如果你创建的 Buffer 对象大于 8Kb,则会将一个 SlowBuffer 对象作为slab,这个slab将会被这个大Buffer 对象独占。


      2.1 Buffer 转换

       Buffer 对象可以与字符串之间互相转换。目前支持的字符编码类型有如下几种:
  • ASCII
  • UTF-8
  • UTF-16LE/UCS-2
  • Base64
  • Binary
  • Hex

         2.2 字符串转Buffer 

字符串转 Buffer 主要是通过构造函数完成的:
         
new Buffer(str,[encoding])

通过构造函数转换的 Buffer 只能储存一种编码类型。encoding 参数不传时默认是 utf-8;
一个 Buffer 对象可以储存不同编码类型的字符串转码的值,调用 write() 方法可以实现该目标。
buf.write(str,[offset],[length],[encoding])

  虽然你可以这样子做,但是你要当心每种编码的字节长度不同,将 Buffer 反转回字符串的时候需要谨慎的处理。·

2.2 Buffer 转字符串

将 Buffer 转回字符串得操作也很简单,是用Buffer对象的 toString() 可以将Buffer 对象转换为字符串,代码如下:
buf.toString([encoding],[start],[end])

比较好的是,可以设置encoding(默认是UTF-8),start,end 这3个参数实现整体或者局部的转换。
 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值