Node中的Buffer类怎么使用(buffer,node,web开发)

时间:2024-05-03 21:54:30 作者 : 石家庄SEO 分类 : web开发
  • TAG :

Buffer.from(arrayBuffer[, byteOffset[, length]])

说完了buffer参数,我们再来说一下arrayBuffer参数,它的表现和buffer是有很大的区别的。ArrayBuffer是ECMAScript定义的一种数据类型,它简单来说就是一片你不可以直接(或者不方便)使用的内存,你必须通过一些诸如Uint16ArrayTypedArray对象作为View来使用这片内存,例如一个Uint16Array对象的.buffer属性就是一个ArrayBuffer对象。当Buffer.from函数接收一个ArrayBuffer作为参数时,Node会创建一个新的Buffer对象,不过这个Buffer对象指向的内容还是原来ArrayBuffer的内容,没有任何的数据拷贝行为。我们来看个例子:

constarr=newUint16Array(2)

arr[0]=5000
arr[1]=4000

constbuf=Buffer.from(arr.buffer)

console.log(buf)
//Prints:<Buffer8813a00f>

//改变原来数组的数字
arr[1]=6000

console.log(buf)
//Prints:<Buffer88137017>

从上面例子的输出我们可以知道,arrbuf对象会共用同一片内存空间,所以当我们改变原数组的数据时,buf的数据也会发生相应的变化。

其它Buffer操作

看完了创建Buffer的几种做法,我们接着来看一下Buffer其它的一些常用API或者属性

buf.length

这个函数会返回当前buffer占用了多少字节

//创建一个大小为1234字节的Buffer对象
constbuf1=Buffer.alloc(1234)
console.log(buf1.length)
//Prints:1234

constbuf2=Buffer.from('Hello')
console.log(buf2.length)
//Prints:5

Buffer.poolSize

这个字段表示Node会为我们预创建的Buffer池子有多大,它的默认值是8192,也就是8KB。Node在启动的时候,它会为我们预创建一个8KB大小的内存池,当用户用某些API(例如Buffer.alloc)创建Buffer实例的时候可能会用到这个预创建的内存池以提高效率,下面是一个具体的例子:

constbuf1=Buffer.from('Hello')
console.log(buf1.length)
//Prints:5

//buf1的buffer属性会指向其底层的ArrayBuffer对象对应的内存
console.log(buf1.buffer.byteLength)
//Prints:8192

constbuf2=Buffer.from('World')
console.log(buf2.length)
//Prints:5

//buf2的buffer属性会指向其底层的ArrayBuffer对象对应的内存
console.log(buf2.buffer.byteLength)
//Prints:8192

在上面的例子中,buf1buf2对象由于长度都比较小所以会直接使用预创建的8KB内存池。其在内存的大概表示如图:Node中的Buffer类怎么使用这里值得一提的是只有当需要分配的内存区域小于4KB(8KB的一半)并且现有的Buffer池子还够用的时候,新建的Buffer才会直接使用当前的池子,否则Node会新建一个新的8KB的池子或者直接在内存里面分配一个区域(FastBuffer)。

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

这个函数可以按照一定的偏移量(offset)往一个Buffer实例里面写入一定长度(length)的数据。我们来看一下具体的例子:

constbuf=Buffer.from('Hello')

console.log(buf.toString())
//Prints:"Hello"

//从第3个位置开始写入'LLO'字符
buf.write('LLO',2)
console.log("HeLLO")
//Prints:"HeLLO"

这里需要注意的是当我们需要写入的字符串的长度超过buffer所能容纳的最长字符长度(buf.length)时,超过长度的字符会被丢弃:

constbuf=Buffer.from('Hello')

buf.write('LLO!',2)
console.log(buf.toString())
//Print:s"HeLLO"

另外,当我们写入的字符长度超过buffer的最长长度,并且最后一个可以写入的字符不能全部填满时,最后一个字符整个不写入:

constbuf=Buffer.from('Hello')

buf.write('LL你',2)
console.log(buf.toString())
//Prints"HeLLo"

在上面的例子中,由于"你"是中文字符,需要占用三个字节,所以不能全部塞进buf里面,因此整个字符的三个字节都被丢弃了,buf对象的最后一个字节还是保持"o"不变。

Buffer.concat(list[, totalLength])

这个函数可以用来拼接多个Buffer对象生成一个新的buffer。函数的第一个参数是待拼接的Buffer数组,第二个参数表示拼接完的buffer的长度是多少(totalLength)。下面是一个简单的例子:

constbuf1=Buffer.from('Hello')
constbuf2=Buffer.from('World')

constbuf=Buffer.concat([buf1,buf2])
console.log(buf.toString())
//Prints"HelloWorld"

上面的例子中,因为我们没有指定最终生成Buffer对象的长度,所以Node会计算出一个默认值,那就是buf.totalLength = buf1.length + buf2.length。而如果我们指定了totalLength的值的话,当这个值比buf1.lengh + buf2.length小时,Node会截断最后生成的buffer;如果指定的值比buf1.length + buf2.length大时,生成buf对象的长度还是totalLength,多出来的位数填充的内容是0。

这里还有一点值得指出的是,Buffer.concat最后拼接出来的Buffer对象是通过拷贝原来Buffer对象得出来,所以改变原来的Buffer对象的内容不会影响到生成的Buffer对象,不过这里我们还是需要考虑拷贝的性能问题就是了。

Buffer对象的垃圾回收

在文章刚开始的时候我就说过Node所有的Buffer对象分配的内存区域都是独立于V8堆空间的,属于堆外内存。那么是否这就意味着Buffer对象不受V8垃圾回收机制的影响需要我们手动管理内存了呢?其实不是的,我们每次使用Node的API创建一个新的Buffer对象的时候,每个Buffer对象都在JavaScript的空间对应着一个对象(Buffer内存的引用),这个对象是受V8垃圾回收控制的,而Node只需要在这个引用被垃圾回收的时候挂一些钩子来释放掉Buffer指向的堆外内存就可以了。简单来说Buffer分配的空间我们不需要操心,V8的垃圾回收机制会帮我们回收掉没用的内存

相信大家对“Node中的Buffer类怎么使用”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注亿速云行业资讯频道。

本文:Node中的Buffer类怎么使用的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:jquery可不可以用this下一篇:

11 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18