Node.js的Buffer写入

JavaScript064

Node.js的Buffer写入,第1张

Buffer写入的语法如下:

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

即根据encoding的字符编码写入string到buf中的offset位置。length参数是写入的字节数。如果buf没有足够的空间保存整个字符串,就只会写入string的一部分。只部分解码的字符不会被写入。该方法返回实际写入的大小。参数含义如下:

    ●    String:写入的字符串。

    ●    Offset:开始写入的索引值,默认为0。

    ●    Length:写入的字节数,默认为buffer.length。

    ●    Encoding:使用的编码,默认为"utf8"。

Buffer实例一般用于表示编码字符的序列,如UTF-8、UCS2、Base64或十六进制编码的数据。通过使用显式的字符编码就可以在Buffer实例与普通的JavaScript字符串之间进行相互转换。 Node.js目前支持的字符编码包括: ●    ascii:仅支持7位ASCII数据。如果设置去掉高位的话,那么这种编码是非常快的。 ●    utf8:多字节编码的Unicode字符。许多网页和其他文档格式都使用UTF-8。 ●    utf16le:2或4个字节,小端序编码的Unicode字符,支持代理对(U+10000 ~ U+10FFFF)。 ●    ucs2:utf16le的别名。 ●    base64:Base64编码。 ●    latin1:一种把Buffer编码成一字节编码的字符串的方式。 ●    binary:latin1的别名。 ●    hex:将每个字节编码为两个十六进制字符。

Buffer结构

Buffer是一个典型的Javascript和C++结合的模块,性能相关部分用C++实现,非性能相关部分用javascript实现。

Node在进程启动时Buffer就已经加装进入内存,并将其放入全局对象,因此无需require

Buffer对象:类似于数组,其元素是16进制的两位数。

Buffer内存分配

Buffer对象的内存分配不是在V8的堆内存中,在Node的C++层面实现内存的申请。

为了高效的使用申请来得内存,Node中采用slab分配机制,slab是一种动态内存管理机制,应用各种*nix操作系统。slab有三种状态:

(1) full:完全分配状态

(2) partial:部分分配状态

(3) empty:没有被分配状态

Buffer的转换

Buffer对象可以和字符串相互转换,支持的编码类型如下:

ASCII、UTF-8、UTF-16LE/UCS-2、Base64、Binary、Hex

字符串转Buffer

new Buffer(str, [encoding]),默认UTF-8

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

Buffer转字符串

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

Buffer不支持的编码类型

通过Buffer.isEncoding(encoding)判断是否支持

iconv-lite:纯JavaScript实现,更轻量,性能更好无需C++到javascript的转换

iconv:调用C++的libiconv库完成

Buffer的拼接

注意 "res.on('data', function(chunk) {})",其中的参数chunk是Buffer对象,直接用+拼接会自动转换为字符串,对于宽字节字符可能会导致乱码产生

解决方法:

(1) 通过可读流中的setEncoding()方法,该方法可以让data事件传递不再是Buffer对象,而是编码后的字符串,其内部使用了StringEncoder模块。

(2) 将Buffer对象暂存到数组中,最后在组装成一个大Buffer让后编码转换为字符串输出。

Buffer在文件I/O和网络I/O中广泛应用,其性能举足轻重,比普通字符串性能要高出很多。

Buffer的使用除了与字符串的转换有性能损耗外,在文件读取时候,有一个highWaterMark设置对性能影响至关重要。

a,highWaterMark设置对Buffer内存的分配和使用有一定影响。

b, highWaterMark设置过小,可能导致系统调用次数过多。

什么时候该用buffer,什么时候不该用  ------ 纯粹的javascript支持unicode码而对二进制不是很支持,当解决TCP流或者文件流的时候,处理流是有必要的,我们保存非utf-8字符串,2进制等等其他格式的时候,我们就必须得使用 ”Buffer“ 。