Buffer是nodeJS中的二进制缓存操做模块内容。先来看一段简短的代码。javascript
// 建立一个长度为 十、且用 0 填充的 Buffer。
const buf1 = Buffer.alloc(10); // 建立一个长度为 十、且用 0x1 填充的 Buffer。 const buf2 = Buffer.alloc(10, 1); // 建立一个长度为 十、且未初始化的 Buffer。 // 这个方法比调用 Buffer.alloc() 更快, // 但返回的 Buffer 实例可能包含旧数据, // 所以须要使用 fill() 或 write() 重写。 const buf3 = Buffer.allocUnsafe(10); // 建立一个包含 [0x1, 0x2, 0x3] 的 Buffer。 const buf4 = Buffer.from([1, 2, 3]); // 建立一个包含 UTF-8 字节 [0x74, 0xc3, 0xa9, 0x73, 0x74] 的 Buffer。 const buf5 = Buffer.from('tést'); // 建立一个包含 Latin-1 字节 [0x74, 0xe9, 0x73, 0x74] 的 Buffer。 const buf6 = Buffer.from('tést', 'latin1');
由上面可知,实际上buffer对象内容展现给咱们的时候其实是一连串的二进制形式的内容,固然咱们能够经过不一样的二进制编码标准来转化当前的字符串内容,经常使用的编码(固然也是默认的)是UTF8,这是JS一向使用的编码方式,咱们也能够选择ascii等等其余类型的编码。下面咱们来了解一下Buffer模块中的一些方法吧。java
首先须要知道的一点就是在新版本的nodeJS之中buffer的构造器获取相关的值的方式已经摈弃了,如今主要是三个Buffer的类方法。下面咱们先来了解一下这三个方法内容。node
-- Buffer.alloc(size, [fill, [encoding]]):传递的三个参数分别为,buffer的大小,填充每个占位的字符内容,以及以什么编码格式初始化,编码格式默认为UTF8。这里上一段代码。。。编程
console.log(Buffer.alloc(10)); //展现 <Buffer 00 00 00 00 00 00 00 00 00 00> console.log(Buffer.alloc(10, 1)); //展现 <Buffer 01 01 01 01 01 01 01 01 01 01> console.log(Buffer.alloc(10, 300)); //展现 <Buffer 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c>
由上面能够看出其是以两位16进制数来进行数据的填充的,当咱们的想要是使用300进行填充的时候,实际上其转换成为而进制的时候为9位,这node将其内容舍弃了最高位,由此编程了2C即44。数组
-- Buffer.allocUnsafe(size): 这一方法内容传递的是分配内存大小,可是并不会自动的填充内容。Buffer会将内存模块内容分配制定的大小并返回,可是能够从方法内容来看到这一方法是不安全的,由于不自动填充,因此其中分配出来的内存块内容可能存在以前的数据内容,可能会致使安全的问题。可是因为这一函数的快速和便捷因此有时仍是会使用,可是通常最好仍是和fill方法同时使用,能够将分配的内存中的数据替换掉,并保证安全性。缓存
-- Buffer.allocUnsafeSlow(size): 这是另一个不安全的方法内容,一样是分配一个size大小的内存区域,可是和上面方法不一样的地方是,这一方法不初始化底层内存信息,固然企业有可能包含敏感信息,因此也须要配合fill方法来使用。(而allocUnsafe方法,当分配的内存小于 4KB 时,默认会从一个单一的预分配的 Buffer 切割出来。 这使得应用程序能够避免垃圾回收机制因建立太多独立分配的 Buffer 实例而过分使用。 这个方法经过像大多数持久对象同样消除追踪与清理的需求,改善了性能与内存使用。)安全
-- Buffer.from():from方法内容传递的内容和alloc-开头的方法不一样了,这一方法传递的是数组,字符串参数或者是一个buffer对象内容。咱们直接上代码。函数
这一段代码能够充分说明Buffer.from的多态了。固然要注意的一点就是在传递的数据为数组的时候,其中的起始位置内容其实是无效的,只有当咱们传递的第一个参数是ArrayBuffer,即Buffer数组才行。性能
-- Buffer.byteLength(string,[encoding]): 返回一个字符串字符数,第二个参数可能会影响到返回内容的长度,由于不一样的编码内容会影响当前字符内容的转化方式。测试
-- Buffer.compare(buf1, buf2): 比较两个buffer对象内容,一般用于数组排序。
-- Buffer.concat(list, [totalLength]):合并Buffer或者是Uint8Array的实力数组。
-- Buffer.isBuffer(obj):判断传递的参数是否是Buffer对象。
-- Buffer.isEncoding(encode):判断当前的Buffer内容的编码与传递的编码格式是否相同。
-- Buffer.poolSize:用于决定预分配的、内部 Buffer 实例池的大小的字节数。 这个值能够修改。
以上是Buffer模块提供的类方法内容,固然其针对实例对象该内容也是有许多的内容。接下来咱们来看一看。
-- 受限咱们须要知道的是其实Buffer对象相似于数组的,咱们能够经过下标的形式来获取相应位置的值,看一段代码吧
图中展现能够看出,咱们获取的Buffer对象其实是以每一个8位内容为一个数位。用相似数组的下标形式来获取相应的数位内容。固然找事出来的内容和其中Buffer对象实例的内容是不相同的是由于,实例中的每个数位用的是16进制的形式展现的,而当咱们获取相关的数据的时候则转变成为了10进制。
-- 实例对象之中有一个buffer属性,能够获取底层的ArrayBuffer对象内容。直接上代码。
> te.buffer
ArrayBuffer { byteLength: 8192 }
咱们这里说明一下ArrayBuffer对象吧。这一内容能够在MDN中的javascript标准库中的看到,引用文档中说明 —— ArrayBuffer对象被用来表示一个通用的,固定长度的原始二进制数据缓冲区,可是用户对于这一对象的内容是不能进行直接性质的额操做的。咱们能够经过使用类型化数组对象内容或者是DataView对象内容来进行缓冲区数据内容的读写。这里所说的类型化数组对象其实就是TypedArray对象,可是其实不能经过new来直接获取新的对象的,可是存在不少的方法能够获取这一对象的实例内容,例如以下方法。
Int8Array();
Uint8Array();
Uint8ClampedArray();
Int16Array();
Uint16Array();
Int32Array();
Uint32Array();
Float32Array();
Float64Array();
这些方法的调用能够直接获取TypedArray对象内容,具体内容能够看一看MDN这里就不在细说了。这里有一个TypedArray的博客内容(点这里)
-- buf.compare(target[, targetstart [, targetend [, sourcestart [, sourceend]]]]):主要的参数就是target,传递的是要与buf对象比较的另外一个Buffer对象,后面的参数都是偏移量一类的内容咯。相信字面上仍是很好理解的。其返回结果却是须要说明一下,其标明在buf在排序上面排在target前,后,或是相同位置。比较的方式是基于实际的字符串序列,若是target与buf相同则是0,若是target排在buf前面则返回1,若是排在buf后面则返回-1,看段代码:
-- buf.entries():返回一个遍历对象,经过for... of循环来遍历,返回的是[index, value]的形式的选项内容。上代码:
const buf = Buffer.from('buffer');
// 输出:
// [0, 98]
// [1, 117]
// [2, 102]
// [3, 102]
// [4, 101]
// [5, 114]
for (const pair of buf.entries()) { console.log(pair); }
-- buf,equals(otherBuffer):比较当前两个Buffer对象内容,若是两个Buffer对象拥有相同的字符级内容,则返回相同,不然返回false
-- buf.fill(value [, offset [, end]] [, encoding]): 填充函数,以前的代码中也有已使用到,填充Buffer对象中的每个数位为传递的参数内容。
-- buf.include(value [, byteoffset] [, encoding]):测试当前的buffer对象之中是否囊括了传递进入的value值,value的类型能够是字符串,buffer对象或者是整数。第二个数字内容是肯定从Buf对象的第几个数位开始查找内容,第三个参数只有在Value内容为字符串的状况之下才能生效,表示将会把value转化成为何编码形式的内容来比对。
-- buf.indexOf(value [,byteoffset] [,encoding]):测试当前的value是否存在于Buf对象之中,存在则返回匹配起始位置的下标,不存在则返回-1。感受和字符串的indexOf的内容很像。
-- buf.keys()这一函数的做用是建立一个包含buf索引的迭代器。
-- buf.lastIndexOf():这一函数传递的参数内容与indexOf相同,做用也是相似,只是其返回的再也不是陪陪的第一个字符串的位置了,而是最后一段匹配的字符串的位置。
固然还有其余的一些经常使用或是很是用的Buffer对象的方法,这里就不一一介绍了。能够阅读相关的文档内容。