ch05 利用Buffer类处理二进制数据
1.在客户端JavaScript脚本代码中,对于二进制数据并没有提供一个很好的支持,然而,在处理TCP流或文件流时,必须要处理二进制数据。因此,在node.js中,定义了一个Buffer类,该类用来创建一个专门存放二进制数据的缓存区。
创建Buffer对象
在node.js中,Buffer类是一个可以在任何模块中被利用的全局类,不需要为该类的使用而加载任何模块。可以使用new关键字来创建该类的实例对象。
Buffer类有三种形式的构造函数:
第一种:
只需将缓存区大小(以字节为单位)指定为构造函数的参数,用法:new Buffer(size)
被创建的Buffer对象拥有一个length属性,属性值为缓存区大小
可以使用Buffer对象的fill方法来初始化缓存区中的所有内容,用法:buf.fill(value, [offset],[end])
—— 第一个参数为必须指定的参数,参数值为需要被写入的数值;
——第二个参数与第三个参数为可选参数,其中第二个参数用于指定从第几个字节处开始写入被制定的数值,默认为0,即从缓存区的起始位置写入,第三个参数用于指定将数值一直写入到第几字节处,默认值为buffer对象的大小,即书写到缓存区底部
第二种:
直接使用一个数组来初始化缓存区,用法:new Buffer(array)
在这种形式的构造函数中,使用了一个存放了需要被指定数值的数组来作为构造函数的参数。
第三种:
直接使用一个字符串来初始化缓存区,具体用法:new Buffer( str, [encoding])
在这种形式的构造函数中,使用2个参数,其中第一个参数为必须指定的参数,参数值为用于初始化缓存区的字符串,第二个参数值为一个用于指定文字编码格式的字符串,默认为“utf-8”.
在node.js中,将自动执行字符串的输入输出时的编码与解码处理,默认使用utf-8编码,当使用字符串参数来创建buffer对象并初始化缓存区时,如果使用不同的编码格式,则缓存区中的数据也会有所不同。
字符串的长度与缓存区的长度
在node.js中,一个字符串的长度与根据该字符串所创建的缓存区的长度并不相同,因为在计算字符串长度是,以文字作为一个单位,而计算缓存区的长度时,以字节作为一个单位。
字符串对象一旦创建后不可被修改,而buffer对象是可以被修改的,可以通过序号来修改其中某个字节处的数据
字符串对象拥有搜索字符的index()方法、match()方法与search()方法,可用于替换文字的replace方法以及取出部分字符的substring方法,但是buffer对象并不具有这些方法,只有一个用于取出指定位置处数据的slice方法,该方法的使用方法与string对象的slice方法相同
buffer对象的slice方法并不是复制缓存区的数据,而是与该数据共享内存区域,因此,如果修改使用slice方法取出的数据,则缓存区中保存的数据也将被修改
buffer对象与字符串对象之间的相互转换
1.buffer对象的toString方法:
可以将Buffer对象中保存的数据转换为字符串,使用方法如下:
buf.toString( [encoding], [start], [end])
三个可选参数,第一个参数用于指定buffer对象中保存的文字编码格式,默认参数为utf-8
第二个和第三个参数用于指定被转换数据的起始位置与终止位置,以字节为单位。
2.buffer对象的write方法:
如果要将字符串当做二进制数据来使用,只需要将字符串作为buffer类的构造函数的从参数来创建buffer对象即可。但是有时我们需要向已经创建的buffer对象中写入字符串,具体用法:
buf.write( string, [offset]; [length], [encoding])
四个参数,其中第一个参数为必须指定参数,后三个参数为可选参数。
第一个参数用于指定需要写入的字符串,第二个参数offset与第三个参数length用于指定字符串转换为字节数据后的写入位置。第四个参数用于指定写入字符串时使用的编码格式,默认为utf-8格式
3.StringDecoder对象
在node.js中,可以使用StringDecoder对象将Buffer对象中的数据转换为字符串,该对象的作用与Buffer对象的toString方法的作用相同,但是对utf-8编码格式的字符串提供更好的支持。
在使用StringDecoder对象时,首先需要加载Node.js中的string_decoder模块,用法如下:
var StringDecoder=require('string_decoder').StringDecoder;
加载了string_decoder模块后,可以创建一个StringDecoder对象,方法如下:
var decoder=new StringDecoder([encoding]);
在StringDecoder类的构造函数中,可以使用一个可选参数,该参数用于指定转换字符串时所使用的编码格式,默认参数值为utf-8
在需要将Buffer对象的数据转换为字符串时,可以使用StringDecoder对象的write方法,代码如下所示:
decode.write(buffer)
在stringDecoder对象的write方法中,可以使用一个参数,用于指定需要被转换的buffer对象,该方法返回转换后的字符串。
StringDecoder对象的有用之处在于,当需要将多个Buffer对象的二进制数据转换为文字的场合。
4.Buffer对象与数值对象之间的相互转换
JavaScript中,所有的数值都是number对象,虽然在其他语言中,可能存在int和float这种明显的区别
虽然在JavaScript中,只需要一个number对象就够了,但是从文件中读取数据或向文件中写入数据的场合中,有些还是需要明确知道数据的类型。
在node.js中,为buffer对象准备了将buffer对象中的二进制数据读取为JavaScript中的number类型的数据,或将number类型的数据转换为精确类型后向buffer中写入的方法
read系列的方法均用于将buffer对象中的数据读取为number类型的数据,其中第一个参数offset用于指定获取数据的起始位置,以字节为单位,第二个参数noAssert为一个布尔类型的可选参数,用于指定是否对offset的值进行验证。参数值为false时,如果offset参数超出了缓存区的长度,则抛出AssertionError异常,参数值为true时,则不抛出该异常,默认值为false。
write系列的方法均用于将number类型的数据转换为指定数据类型后写入到缓存区中,
-第一个参数为需要写入的数据
-第二个参数(offset)用于指定数据的起始写入位置,以字节为单位。
-第三个参数为一个布尔类型的可选参数,用于指定是都对offset的值进行验证。参数值为false时,如果offset参数值超出了缓存区的长度,则抛出AssertionError异常,参数值为true时,则不抛出该异常,默认值为false。
5.Buffer对象与JSON对象之间的相互转换
在Node.js中,可以使用JSON.stringify方法将Buffer对象中保存的数据转换为一个字符串,也可以使用JSON.parse方法将一个经过转换后的字符串还原为一个数组。
6 复制缓存数据
当需要将Buffer对象中保存的二进制数据复制到另一个Buffer对象中时,可以使用Buffer对象的copy方法,copy方法的使用方法如下所示。
buf.copy(targetBuffer, [targetStart], [sourceStart], [sourceEnd])
在Buffer对象的copy方法中,使用四个参数,其中第一个参数为必须指定的参数,其余三个参数均为可选参数。
第一个参数用于指定复制的目标Buffer对象。
第二个参数用于指定目标Buffer对象中从第几个字节开始写入数据,参数值为一个小于目标Buffer对象长度的整数值,默认值为0(从开始处写入数据)
第三个参数用于指定从复制源Buffer对象中获取数据时的开始位置,默认值为0,即从复制源Buffer对象中的第一个字节开始获取数据,
第四个参数用于指定从复制源Buffer对象中获取数据时的结束位置,默认值为复制源Buffer对象的长度,即一直获取完毕复制源Buffer对象中的所有剩余数据。
7 Buffer类的类方法
在Node.js中,对Buffer类定义了三个类方法(相当于其他语言中的静态方法,在Node.js中称为类方法)
7.1 isBuffer方法
isBuffer方法用于判断一个对象是否为一个Buffer对象,使用方法如下所示。
Buffer.isBuffer(obj)
在isBuffer方法中,使用一个参数,用于指定需要被判断的对象,如果对象为Buffer对象,方法返回true,否则返回false。
7.2 byteLength方法
使用byteLength方法计算一个指定字符串的字节数,使用方法如下所示
Buffer.byteLength ( string, [encoding])
-第一个参数为必须输入参数,用于指定需要计算字节数的字符串
-第二个参数为可选参数,用于指定按什么编码方式来计算字节数,默认值为utf8。
7.3 concat方法
concat方法用于将几个Buffer对象结合创建为一个新的Buffer对象,用法如下:
Buffer.concat(list, [totalLength])
第一个参数为必须指定的参数,参数值为一个存放了多个Buffer对象的数组,concat方法将把其中的所有Buffer对象联结创建为一个Buffer对象
第二个参数为可选参数,用于指定被创建的Buffer对象的总长度,当省略该参数时,被创建的Buffer对象为第一个参数数组中所有Buffer对象的长度的合计值。
7.4 isEncoding方法
用于检测一个字符串是否为一个有效的编码格式字符串,使用方法如下所示
buffer.isEncoding(encoding)
在isEncoding方法中,使用一个参数,用于指定需要被检测的字符串。如果该字符串为有效的编码格式字符串,则方法返回true,如果该字符串不是一个有效的编码格式字符串,则方法返回false。