使用buffer类处理二进制数据

在客户端javascript脚本代码中,对于二进制数据并没有提供一个很好的支持。然后在nodejs中需要处理像TCP流或文件流时,必须要处理二进制数据。因此在node.js中,定义了一个Buffer类,该类用来创建一个专门存放二进制数据的缓存区。

一:创建Buffer对象

在node.js中,Buffer类是一个可以在任何模块被利用的全局类,不需要为该类的使用而加载任何模块。可以使用new关键字来创建该类的实例对象。Buffer类可以使用三种方式来构造函数,第一种方式如下:

    new Buffer(size)

被创建的buffer对象拥有一个length属性,属性值为缓存区的大小。如下:

我们现在也可以使用Buffer对象的fill方法来初始化缓存区中的所有内容,如下所示:

    buf.fill(value,[offset],[end]);

在Buffer对象的fill方法中,可以使用三个参数,第一个参数为必须指定的参数,参数值为需要被写入的数值,第二个参数与第三个参数为可选参数,其中第二个参数用于指定从第几个字节处开始写入被指定的数值,默认值为0,即从缓存区的起始位置写入,第三个参数用于指定将数值一直写入到第几个字节处,默认值为Buffer对象的大小,即书写到缓存区的底部。

现在我们希望从buffer对象的缓存区的第10字节处开始写入1,一直到缓存区底部,如下所示:

我们现在也可以在缓存区的第20到第30字节处(从第20字节开始,不包含第30字节)填入2,演示如下:

Buffer类的第二种形式的构造函数是直接使用一个数组来初始化缓存区,代码如下所示:

    new Buffer(array)

演示如下:

Buffer类的第三种形式的构造函数是直接使用一个字符串来初始化缓存区,代码如下:

   new Buffer(str,[encoding]);

第一个参数为必须指定的参数,参数值为用于初始化换出区的字符串,第二个参数值为一个用于指定文字编码格式的字符串,默认值为utf-8

如下所示:

在Node.js中,将自动执行字符串的输入输出时的编码与解码处理,默认使用utf-8编码,可以使用编码格式如下表所示:

 编码  说明
 ascii  ASCLL字符串
 utf8  UTF-8字符串
 utf16le  UTF-16LE字符串
 ucs2  UCS2字符串
 base64  经过BASE64编码后的字符串
 binary  二进制数据(不推荐使用)
 hex  使用16进制数值表示的字符串

当使用字符串参数来创建buffer对象并初始化缓存区时,如果使用不同的编码格式,则缓存区中的数据也会有所不同,如下演示:

二:字符串的长度与缓存区的长度

在node.js中,一个字符串的长度与根据该字符串所创建的缓存区的长度并不相同,因为在计算字符串的长度时,是以文字作为一个单位,而在计算缓存区的长度时,是以字节作为一个单位。

比如针对 ”我喜爱编程”这个字符串,该字符串对象的length属性值与根据该字符串创建的buffer对象的length属性值并不相同。因为字符串对象的length属性值获取的是文字个数,而buffer对象的length属性值获取的是缓存区的长度,即缓存区中的字节。

另外,可以使用0开始的序号来取出字符串对象或缓存区中的数据。但是,在获取数据时,字符串对象是以文字作为一个单位,而缓存区对象是以字节作为一个单位。比如,针对一个引用了字符串对象的str变量来说,str[2]获取的是第三个文字,而针对一个引用了缓存区对象的buf对象来说,buf[2]获取的是缓存区中的第三个字节数据转换为整数后的数值。如下:

而buffer对象是可以被修改的。可以通过序号来修改其中某个字节处的数据。如下:

Buffer对象还有一个用于取出指定位置处数据的slice方法,该方法的使用方法与string对象的slice方法相同。

注意:由于buffer对象的slice方法并不是复制缓存区中的数据,而是与该数据共享内存区域,因此,如果修改使用slice方法取出的数据,则缓存区中保存的数据也将被修改。如下演示:

三:Buffer对象与字符串对象之间的相互转换;

    1.   Buffer对象的toString方法

可以使用Buffer对象的toString方法将Buffer对象中保存的数据转换为字符串,使用方法如下所示:

     buf.toString([encoding],[start],[end]);

在Buffer对象的toString方法中,可以使用三个可选参数,第一个参数用于指定Buffer对象中保存的文字编码格式,默认参数值为utf8,第二个及第三个用于指定被转换数据的起始位置和终止位置,以字节为单位。toString方法返回经过转换后的字符串。

四:Buffer对象的write方法

如果要将字符串当做二进制数据来使用,只需将该字符串作为Buffer类的构造函数的参数来创建Buffer对象即可。但是有时候我们需要向已经创建好的Buffer对象中写入字符串,这时候我们可以使用Buffer对象的write方法,代码如下所示:

buf.write(string,[offset],[length],[encoding]);

在buffer对象的write方法中,可以使用四个参数,第一个参数为必须指定的参数,后三个参数为可选参数,第一个参数用于指定需要写入的字符串,第二个参数offset与第三个参数length用于指定字符串转换为字节数据的写入位置。字节数据的书写位置为从第1+offset个字节开始到offset+length个字节为止(列如offset为3,length为8,写入位置为从第4个字节开始到第11个字节为止,包括第4个字节与第11个字节)。第四个参数用于指定写入字符串时使用的编码格式,默认是utf8格式。

如下代码演示:

五:Buffer对象与JSON对象之间的相互转换

在Node.js中,可以使用JSON.stringfy方法将Buffer对象中保存的数据转换为一个字符串,也可以使用JSON.parse方法将一个经过转换后的字符串还原为一个数组。

六:复制缓存数据。

当需要将Buffer对象中保存的二进制数据复制到另一个Buffer对象中时,可以使用Buffer对象的copy方法,copy方法的使用方法如下所示:

buf.copy(targetBuffer,[targetStart],[sourceStart],[sourceEnd]);

在Buffer对象的copy方法中,使用四个参数,第一个参数为必须指定的参数,其余三个参数均为可选参数。第一个参数用于指定复制的目标Buffer对象。第二个参数用于指定目标Buffer对象中从第几个字节开始写入数据,参数值为一个小于目标的Buffer对象长度的整数值,默认值为0(从开始处写入数据)。第三个参数用于指定从复制源Buffer对象中获取数据时的开始位置,默认值为0,即从复制源Buffer对象中的第一个字节开始获取数据,第四个参数用于指定从复制源Buffer对象中获取数据时的结束位置,默认值为复制源Buffer对象的长度,即一直获取完毕复制源Buffer对象中的所有剩余数据。

比如如下:将a中buffer对象中的内容复制到b中的buffer对象中,复制的目标起始位置为b的buffer对象中的第11字节处(第11字节处开始写入)。如下所示:

七:Buffer类的类方法

  1. isBuffer方法

isBuffer方法用于判断一个对象是否为一个Buffer对象,使用方法如下:

Buffer.isBuffer(obj)

在isBuffer方法中,使用一个参数,用于指定需要被判断的对象,如果对象为Buffer对象,方法返回true,否则返回false。演示如下:

2. byteLength方法;

可以使用byteLength方法计算一个指定字符串的字节数,使用方法如下所示:

     Buffer.byteLength(string,[encoding]);

在byteLength方法中,使用两个参数,第一个参数为必须输入的参数,用于指定需要计算字节数的字符串,第二个参数为可选参数,用于指定按什么编码方式来计算字节数。默认值为utf8.
如下演示:

3. concat方法。

concat方法用于将几个Buffer对象结合创建为一个新的Buffer对象,使用方法如下所示:

Buffer.concat(list,[totalLength])

在concat方法中,使用两个参数,第一个参数为必须指定的参数,参数值为一个存放了多个buffer对象的数组,concat方法将把其中的所有Buffer对象链接创建为一个Buffer对象;第二个参数为可选参数,用于指定被创建的Buffer对象的长度,当省略该参数时,被创建的Buffer对象为第一个参数数组中所有Buffer对象的长度的合计值。

如果一个参数值为一个空数组或第二个参数值等于0,那么concat方法返回一个长度为0的Buffer对象。

如果第一个参数值数组中只有一个Buffer对象,那么concat方法直接返回该Buffer对象。

如果第一个参数值数组中拥有一个以上的Buffer对象,那么concat方法返回被创建的Buffer对象。

如下演示:

4. isEncoding方法。

isEncoding方法用于检测一个字符串是否为一个有效的编码格式字符串,使用方法如下所示:

Buffer.isEncoding(encoding);

在isEncoding方法中,使用一个参数,用于指定需要被检测的字符串。如果该字符串为有效的编码格式字符串,则方法返回true,如果该字符串不是一个有效的编码格式字符串,则方法返回false。如下演示:

bufferd对象详解的更多相关文章

  1. jQuery的deferred对象详解

    jQuery的deferred对象详解请猛击下面的链接 http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_ ...

  2. Window 对象详解 转自 http://blog.csdn.net/jcx5083761/article/details/41243697

    详解HTML中的window对象和document对象 标签: HTMLwindowdocument 2014-11-18 11:03 5884人阅读 评论(0) 收藏 举报 分类: HTML& ...

  3. jQuery的deferred对象详解(转载)

    本文转载自: jQuery的deferred对象详解(转载)

  4. mvc-servlet---ServletConfig与ServletContext对象详解(转载)

    ServletConfig与ServletContext对象详解 一.ServletConfig对象    在Servlet的配置文件中,可以使用一个或多个<init-param>标签为s ...

  5. JS中的event 对象详解

    JS中的event 对象详解   JS的event对象 Event属性和方法:1. type:事件的类型,如onlick中的click:2. srcElement/target:事件源,就是发生事件的 ...

  6. JavaWeb学习----JSP内置对象详解

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  7. django中request对象详解(转载)

    django中的request对象详解 Request 我们知道当URLconf文件匹配到用户输入的路径后,会调用对应的view函数,并将  HttpRequest对象  作为第一个参数传入该函数. ...

  8. (转)javascript中event对象详解

    原文:http://jiajiale.iteye.com/blog/195906 javascript中event对象详解          博客分类: javaScript JavaScriptCS ...

  9. dom对象详解--document对象(二)

       dom对象详解--style对象 style对象 style对象和document对象下的集合对象styleSheets有关系,styleSheets是文档中所有style对象的集合,这里讲解的 ...

随机推荐

  1. JSP传递数组给JS的方法

    由于JSP页面的数组无法直接传到JS.所以采用以下方法来获取数组. <% String[] title = { "姓名 ", "学号 ", "性 ...

  2. react-event-pooling

    react-event-pooling 事件池 https://codesandbox.io/s/3xp4y9zp7q https://reactjs.org/docs/events.html#eve ...

  3. 【WCF】WCF 附录 高级主题 配置服务配额设置

    微软产品自带一个“默认安全”方案.这也包括了WCF,意味着WCF中的多种配置可以设置来阻止诸如DOS(拒绝服务访问)攻击.微软为很多基于一个单一计算机的开发环境选择这样的设置.这也意味着默认设置中的一 ...

  4. Elasticsearch Query DSL备忘(1)(Constant score query和Bool Query)

    Query DSL (Domain Specific Language),基于json的查询方式 1.Constant score query,常量分值查询,目的就是返回指定的score,一般都结合f ...

  5. [牛客练习赛29D]禁止动规

    description newcoder 你在一个无限长的数轴上,一开始你在原点 本来你只有两种操作:向左dp,以及向右dp 然而由于禁止dp 于是你只能另寻出路 万幸的是,dp之神随机给了你n个变量 ...

  6. [JSOI2009]计数问题 二维树状数组

    ---题面--- 题解: 二维树状数组的板子题,,,学了这么久第一次写二维树状数组,惭愧啊. 怎么写就不说了,看代码吧. 跟普通的是一样的写法 #include<bits/stdc++.h> ...

  7. Android ListView的优化

    最近的项目中有通讯录这个模块,里面的通讯录涉及的联系人数量很大,导致在加载页面的时候有点卡,所以就必须得进行优化,优化的最终实现理论是什么?就是让ListView一次性加载的数据较少,后续根据用户操作 ...

  8. BZOJ1509 & 洛谷4408:[NOI2003]逃学的小孩——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=1509 https://www.luogu.org/problemnew/show/P4408 sb ...

  9. [bzoj] 3669 NOI2014 魔法森林 || LCT

    原题 copy一篇题解:原链接 将边按照a排序,然后从小到大枚举,加入图中. 在图中用lct维护一棵两点之间b最大值尽量小的生成树. 当加入一条边(u, v)时: 如果(u, v)不连通,则直接加入这 ...

  10. HDOJ(HDU).2546 饭卡(DP 01背包)

    HDOJ(HDU).2546 饭卡(DP 01背包) 题意分析 首先要对钱数小于5的时候特别处理,直接输出0.若钱数大于5,所有菜按价格排序,背包容量为钱数-5,对除去价格最贵的所有菜做01背包.因为 ...