Node.jsnodeJS之二进制buffer对象

前方的话

  在ES6引入TypedArray以前,JavaScript语言没有读取或操作二进制数据流的编制。Buffer类被引入作为Nodejs的API的一片段,使其得以在TCP流和文件系统操作等景色中拍卖二进制数据流。现在TypedArray已经被添加进ES6中,Buffer类以一种更优与更切合Node.js用例的方法落成了Uint8Array。本文将详细介绍buffer对象

 

概述

  由于应用场景不一样,在Node中,应用须求处理互连网协议、操作数据库、处理图片、接收上传文件等,在网络流和文件的操作中,还要处理大批量二进制数据,JavaScript自有的字符串远远不可能满意这一个需求,于是Buffer对象现身

  Buffer是一个杰出的JavaScript与C++结合的模块,它将品质相关部分用C++达成,将非品质相关的有的用JavaScript完毕。Buffer类的实例类似于整数数组,除了其是大大小小固定的、且在V8堆外分配物理内存。Buffer的高低在其创立时就已规定,且不可能调整大小

  由于Buffer太过大规模,Node在经过启动时就曾经加载了它,并将其放在全局对象(global)上。所以在行使Buffer时,无须通过require()即可直接行使

/*
{ [Function: Buffer]
  poolSize: 8192,
  from: [Function],
  alloc: [Function],
  allocUnsafe: [Function],
  allocUnsafeSlow: [Function],
  isBuffer: [Function: isBuffer],
  compare: [Function: compare],
  isEncoding: [Function],
  concat: [Function],
  byteLength: [Function: byteLength] }
 */
console.log(Buffer);

 

创建

  在 Node.js
v6往日的本子中,Buffer实例是透过Buffer构造函数创立的,它根据提供的参数再次来到区其余 Buffer,而新本子的nodejs则提供了相应的措施

  1、new Buffer(size)。传一个数值作为第四个参数给Buffer()(如new
Buffer(10)),则分配一个点名大小的新建的Buffer对象

  分配给那种Buffer实例的内存是未初叶化的(没有用0填充)。就算那样的宏图使得内存的分配分外快,但已分配的内存段可能含有潜在的敏锐性旧数据

  那种Buffer实例必须手动地被开端化,可以利用buf.fill(0)或写满这一个Buffer。即使那种行为是为了增加质量而故意为之的,但付出经历表明,成立一个很快但未初叶化的Buffer与创造一个慢点但更安全的Buffer之间需求有更引人注目的界别

var buf = new Buffer(5);
console.log(buf);//<Buffer e0 f7 1d 01 00>
buf.fill(0);
console.log(buf);//<Buffer 00 00 00 00 00>

  [注意]当大家为一个Buffer对象分配空间尺寸后,其长度就是平素的,无法更改

var buf = new Buffer(5);
console.log(buf);//<Buffer b8 36 70 01 02>
buf[0] = 1;
console.log(buf);//<Buffer 01 36 70 01 02>
buf[10] = 1;
console.log(buf);//<Buffer 01 79 43 6f 6e>

  【Buffer.allocUnsafe(size)】

   在新本子中,由Buffer.allocUnsafe(size)方法替代,来分配一个大大小小为 size 字节的新建的远非用0填充的Buffer。可以接纳buf.fill(0)初始化Buffer实例为0

var buf = Buffer.allocUnsafe(10);
console.log(buf);//<Buffer 75 63 74 42 79 4c 65 6e 67 74>
buf.fill(0);
console.log(buf);//<Buffer 00 00 00 00 00 00 00 00 00 00>

  【Buffer.alloc(size[, fill[, encoding]])】

  在新本子中,使用Buffer.alloc(size)方法能够生成一个平安的buffer对象,参数size
<Integer> 新建的 Buffer 期望的长度;fill <String> |
<Buffer> | <Integer> 用来预填充新建的 Buffer 的值。 默许:
0;encoding <String> 即使 fill 是字符串,则该值是它的字符编码。
默许: ‘utf8’

  分配一个大小为 size 字节的新建的 Buffer 。 即使 fill 为 undefined
,则该 Buffer 会用 0 填充

var buf = Buffer.alloc(5);
console.log(buf);//<Buffer 00 00 00 00 00>

  2、new
Buffer(array或buffer)。传一个数组或Buffer作为首个参数,则将所传对象的数额拷贝到Buffer 

var buf1 = new Buffer([1, 2, 3, 4, 5]);
console.log(buf1);//<Buffer 01 02 03 04 05>
var buf2 = new Buffer(buf1);
console.log(buf2);//<Buffer 01 02 03 04 05>

  【Buffer.from(array或buffer)】

   在新本子中,由Buffer.from(array或buffer)方法替代

var buf1 = Buffer.from([1, 2, 3, 4, 5]);
console.log(buf1);//<Buffer 01 02 03 04 05>
var buf2 = Buffer.from(buf1);
console.log(buf2);//<Buffer 01 02 03 04 05>

  3、new Buffer(string[,
encoding])。首个参数是字符串,第三个参数是编码形式,默许是’utf-8′

var buf1 = new Buffer('this is a tést');
console.log(buf1.toString());//this is a tést
console.log(buf1.toString('ascii'));//this is a tC)st
var buf2 = new Buffer('7468697320697320612074c3a97374', 'hex');
console.log(buf2.toString());//this is a tést

  Node.js 最近支撑的字符编码包涵:

'ascii' - 仅支持 7 位 ASCII 数据。如果设置去掉高位的话,这种编码是非常快的。
'utf8' - 多字节编码的 Unicode 字符。许多网页和其他文档格式都使用 UTF-8 。
'utf16le' - 2 或 4 个字节,小字节序编码的 Unicode 字符。支持代理对(U+10000 至 U+10FFFF)。
'ucs2' - 'utf16le' 的别名。
'base64' - Base64 编码。当从字符串创建 Buffer 时,这种编码可接受“URL 与文件名安全字母表”。
'latin1' - 一种把 Buffer 编码成一字节编码的字符串的方式。
'binary' - 'latin1' 的别名。
'hex' - 将每个字节编码为两个十六进制字符。

  【Buffer.from(string[, encoding])】

  在新本子中,由Buffer.from(string[, encoding]格局替代

var buf1 = Buffer.from('this is a tést');
console.log(buf1.toString());//this is a tést
console.log(buf1.toString('ascii'));//this is a tC)st
var buf2 = Buffer.from('7468697320697320612074c3a97374', 'hex');
console.log(buf2.toString());//this is a tést

  4、new Buffer(arrayBuffer[, byteOffset [,
length]])。参数arrayBuffer <ArrayBuffer> 一个
ArrayBuffer,或一个 TypedArray 的 .buffer 属性;byteOffset
<Integer> 开首拷贝的目录。默许为 0;length <Integer>
拷贝的字节数。默许为 arrayBuffer.length – byteOffset

var arr = new Uint16Array(2);
arr[0] = 5000;
arr[1] = 4000;
var buf = new Buffer(arr.buffer);
console.log(buf);//<Buffer 88 13 a0 0f>
arr[1] = 6000;
console.log(buf);//<Buffer 88 13 70 17>

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

  在新本子中,由Buffer.from(arrayBuffer[, byteOffset [,
length]])方法替代

var arr = new Uint16Array(2);
arr[0] = 5000;
arr[1] = 4000;
var buf = Buffer.from(arr.buffer);
console.log(buf);//<Buffer 88 13 a0 0f>
arr[1] = 6000;
console.log(buf);//<Buffer 88 13 70 17>

 

类数组

  Buffer对象类似于数组,它的元素为16进制的两位数,即0到255的数值

console.log(Buffer.from('test'));//<Buffer 74 65 73 74>

【长度】

  分歧编码的字符串占用的因素个数各不一样,汉语字在UTF-8编码下占用3个要素,字母和半角标点符号占用1个要素

var buf = Buffer.from('match');
console.log(buf.length);//5
var buf = Buffer.from('火柴');
console.log(buf.length);//6

【下标】

  Buffer受Array类型的熏陶很大,可以访问length属性得到长度,也足以透过下标访问元素

var buf = Buffer.alloc(10); 
console.log(buf.length); // => 10

  上述代码分配了一个长10字节的Buffer对象。我们可以透过下标对它进行赋值

buf[0] = 100;
console.log(buf[0]); // => 100

  要小心的是,给元素的赋值假设小于0,就将该值逐次加256,直到得到一个0到255里头的整数。如若得到的数值高于255,就逐次减256,直到得到0~255距离内的数值。如果是小数,屏弃小数部分,只保留整数部分

buf[0] = -100;
console.log(buf[0]); // 156
buf[1] = 300;
console.log(buf[1]); // 44
buf[2] = 3.1415;
console.log(buf[2]); // 3

【fromcharcode】

  平时地,创设的buffer对象的内容是其uft-8字符编码

var buf = Buffer.from('match'); 
console.log(buf); //<Buffer 6d 61 74 63 68>

  假诺要拜访其对应的字符,则须求使用字符串的Node.js,fromCharCode()方法

console.log(String.fromCharCode(buf[0]));//'m'

 

内存分配

  Buffer对象的内存分配不是在V8的堆内存中,而是在Node的C++层面达成内存的报名的。因为拍卖大批量的字节数据不可以采取须要一些内存就向操作系统申请一点内存的不二法门,那恐怕引致大量的内存申请的系统调用,对操作系统有肯定压力。为此Node在内存的施用上使用的是在C++层面申请内存、在JavaScript中分配内存的策略

  为了快速地利用申请来的内存,Node选择了slab分配机制。slab是一种动态内存管理机制,最早诞生于SunOS操作系统(Solaris)中,近来在一些*nix操作系统中有科普的选拔,如FreeBSD和Linux。简单而言,slab就是一块申请好的定势大小的内存区域。slab具有如下3种情状:full:完全分配情状;partial:部分分配景况;empty:没有被分配情状

  当大家须要一个Buffer对象,可以通过以下方法分配指定大小的Buffer对象:

new Buffer(size);//旧
Buffer.alloc(size);//新

【poolSize】

  poolSize属性是用以决定预分配的、内部 Buffer 实例池的尺寸的字节数。默许地,Node以8KB为界限来区分Buffer是大目的照旧小目标:

Buffer.poolSize = 8 * 1024;

  那个8KB的值也就是各样slab的大小值,在JavaScript层面,以它当作单位单元进行内存的分红

  1、分配小Buffer对象

  如若指定Buffer的高低少于8KB,Node会依据小目的的章程开展分配。Buffer的分红进程中举足轻重选拔一个片段变量pool作为中间处理目的,处于分配情形的slab单元都指向它。以下是分配一个全新的slab单元的操作,它会将新申请的SlowBuffer对象指向它:

var pool;
function allocPool() {
    pool = new SlowBuffer(Buffer.poolSize);
    pool.used = 0;
}

  构造小Buffer对象时的代码如下:

new Buffer(1024);//旧
Buffer.alloc(1024);//新

  这一次社团将会去检查pool对象,如若pool没有被创建,将会创设一个新的slab单元指向它:

if (!pool || pool.length - pool.used < this.length) allocPool();

  同时当前Buffer对象的parent属性指向该slab,并记录下是从那一个slab的哪个岗位(offset)起初应用的,slab对象自我也记录被利用了有点字节,代码如下:

this.parent = pool; 
this.offset = pool.used; 
pool.used += this.length;
if (pool.used & 7) pool.used = (pool.used + 8) & ~7;

  那时候的slab状态为partial。当再度创立一个Buffer对象时,构造进程少将会判定这些slab的多余空间是或不是丰富。若是丰硕,使用剩余空间,并更新slab的分红境况。上边的代码创制了一个新的Buffer对象,它会唤起一回slab分配:

new Buffer(3000);//旧
Buffer.alloc(3000);//新

  假使slab剩余的上空不够,将会协会新的slab,原slab中多余的长空会招致浪费。例如,第一遍结构1字节的Buffer对象,第二次结构8192字节的Buffer对象,由于第二次分配时slab中的空间不够,所以创设并运用新的slab,第三个slab的8KB将会被首个1字节的Buffer对象独占。下边的代码一共动用了三个slab单元:

new Buffer(1);//旧
Buffer.alloc(1);//新
new Buffer(8192);//旧
Buffer.alloc(8192);//新

  要专注的是,由于同一个slab可能分配给五个Buffer对象使用,唯有这么些小Buffer对象在功用域释放并都足以回收时,slab的8KB空间才会被回收。即便创设了1个字节的Buffer对象,不过一旦不自由它,实际可能是8KB的内存没有自由

  2、分配大Buffer对象

  借使须求跨越8KB的Buffer对象,将会一贯分配一个SlowBuffer对象作为slab单元,那个slab单元将会被这么些大Buffer对象独占

// Big buffer, just alloc one
this.parent = new SlowBuffer(this.length); 
this.offset = 0;

  那里的SlowBuffer类是在C++中定义的,尽管引用buffer模块能够访问到它,不过不引进直接操作它,而是用Buffer替代

  下边提到的Buffer对象都是JavaScript层面的,可以被V8的污物回收标记回收。不过其中间的parent属性指向的SlowBuffer对象却来自于Node自身C++中的定义,是C++层面上的Buffer对象,所用内存不在V8的堆中

  综上,真正的内存是在Node的C++层面提供的,JavaScript层面只是选用它。当进行小而屡屡的Buffer操作时,采取slab的编制举办先期申请和将来分配,使得JavaScript到操作系统之间不必有过多的内存申请方面的系统调用。对于大块的Buffer而言,则一向运用C++层面提供的内存,而无需细腻的分红操作

 

转换

  Buffer对象可以与字符串之间交互转换。近年来支撑的字符串编码类型有如下二种:ASCII、UTF-8、UTF-16LE/UCS-2、Base64、Binary、Hex

【write()】

  一个Buffer对象足以储存差异编码类型的字符串转码的值,调用write()方法能够达成该目标

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

  string <String> 要写入 buf 的字符串

  offset <Integer> 开头写入 string 的岗位。默许: 0

  length <Integer> 要写入的字节数。默许: buf.length – offset

  encoding <String> string 的字符编码。默认: ‘utf8’;再次回到:
<Integer> 写入的字节数

  依照 encoding 的字符编码写入 string 到 buf 中的 offset 地点。 length
参数是写入的字节数。 若是 buf 没有丰硕的空中保存整个字符串,则只会写入
string 的一有些。 唯有些解码的字符不会被写入

var buf = Buffer.alloc(5); 
console.log(buf); //<Buffer 00 00 00 00 00>
var len = buf.write('test',1,3);
console.log(buf);//<Buffer 00 74 65 73 00>
console.log(len);/3

  由于可以持续写入内容到Buffer对象中,并且每一趟写入可以指定编码,所以Buffer对象中得以存在各样编码转化后的情节。须要小心的是,每种编码所用的字节长度差异,将Buffer反转回字符串时索要兢兢业业处理

【toString()】

  落成Buffer向字符串的转移也不行简单易行,Buffer对象的toString()可以将Buffer对象转换为字符串

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

  encoding – 使用的编码。默许为 ‘utf8’

  start – 指定初叶读取的目录地方,默许为 0

  end – 停止地方,默认为缓冲区的末段

  重回 – 解码缓冲区数据并应用指定的编码重返字符串

var buf =Buffer.alloc(26);
for (var i = 0 ; i < 26 ; i++) {
  buf[i] = i + 97;
}
console.log( buf.toString('ascii'));//abcdefghijklmnopqrstuvwxyz
console.log( buf.toString('ascii',0,5));//abcde
console.log( buf.toString('utf8',0,5));//abcde
console.log( buf.toString(undefined,0,5));//abcde

【toJSON()】

  将 Node Buffer 转换为 JSON 对象

buf.toJSON()

  返回 buf 的 JSON 格式

var buf = Buffer.from('test');
var json = buf.toJSON(buf);
console.log(json);//{ type: 'Buffer', data: [ 116, 101, 115, 116 ] }

【isEncoding()】

  目前相比较遗憾的是,Node的Buffer对象帮衬的编码类型有限,唯有少数的两种编码类型可以在字符串和Buffer之间转换。为此,Buffer提供了一个isEncoding()函数来判断编码是还是不是支持转换

Buffer.isEncoding(encoding)

  将编码类型作为参数传入上边的函数,若是援救转换重临值为true,否则为false。很不满的是,在中华常用的GBK、GB2312和BIG-5编码都不在接济的行列中

console.log(Buffer.isEncoding('utf8'));//true
console.log(Buffer.isEncoding('gbk'));//false

 

类方法

【Buffer.byteLength(string[, encoding])】

  Buffer.byteLength()方法重临一个字符串的其实字节长度。 那与
String.prototype.length 不一样,因为那再次来到字符串的字符数

  string <String> | <Buffer> | <TypedArray> |
<DataView> | <ArrayBuffer> 要总结长度的值

  encoding <String> 假诺 string 是字符串,则那是它的字符编码。
默许: ‘utf8’

  重回: <Integer> string 包罗的字节数

var str = '火柴';
var buf = Buffer.from(str);
console.log(str.length);//2
console.log(buf.length);//6
console.log(buf.byteLength);//6

【Buffer.compare(buf1, buf2)】

  该格局用于相比 buf1 和 buf2 ,常常用于 Buffer 实例数组的排序。
相当于调用 buf1.compare(buf2) 

  buf1 <Buffer>

  buf2 <Buffer>

  Returns: <Integer>

var buf1 = Buffer.from('1234');
var buf2 = Buffer.from('0123');
var arr = [buf1, buf2];
var result = Buffer.compare(buf1,buf2);
console.log(result);//1
console.log(arr.sort());//[ <Buffer 30 31 32 33>, <Buffer 31 32 33 34> ]

【Buffer.concat(list[, totalLength])】

  该格局重回一个联结了 list 中具备 Buffer 实例的新建的 Buffer

  list <Array> 要合并的 Buffer 实例的数组

  totalLength <Integer> 合并时 list 中 Buffer 实例的总长度

  返回: <Buffer>

  如果 list 中从未元素、或 totalLength 为 0 ,则赶回一个新建的长短为 0
的 Buffer 。假使没有提供 totalLength ,则从 list 中的 Buffer
实例计算得到。 为了计算 totalLength
会导致急需执行额外的轮回,所以提供明确的长短会运行更快

var buf1 = Buffer.alloc(10);
var buf2 = Buffer.alloc(14);
var buf3 = Buffer.alloc(18);
var totalLength = buf1.length + buf2.length + buf3.length;
console.log(totalLength);//42
var bufA = Buffer.concat([buf1, buf2, buf3], totalLength); 
console.log(bufA);//<Buffer 00 00 00 00 ...>
console.log(bufA.length);//42

【Buffer.isBuffer(obj)】

  如果 obj 是一个 Buffer 则返回 true ,否则重返 false

var buf = Buffer.alloc(5);
var str = 'test';
console.log(Buffer.isBuffer(buf));//true
console.log(Buffer.isBuffer(str));//false

 

实例方法

【buf.slice([start[, end]])】

  该方法再次回到一个针对相同原始内存的新建的 Buffer,但做了偏移且通过
start 和 end 索引进行裁剪

  start <Integer> 新建的 Buffer 开头的地点。 默许: 0

  end <Integer> 新建的 Buffer 甘休的职位(不带有)。 默许:
buf.length

  返回: <Buffer>

var buffer1 =Buffer.from('test');
console.log(buffer1);//<Buffer 74 65 73 74>
var buffer2 = buffer1.slice(1,3);
console.log(buffer2);//<Buffer 65 73>
console.log(buffer2.toString());//'es'

  [注意]修改那几个新建的 Buffer 切片,也会同时修改原始的 Buffer 的内存,因为那七个目的所分配的内存是重叠的

var buffer1 =Buffer.from('test');
console.log(buffer1);//<Buffer 74 65 73 74>
var buffer2 = buffer1.slice(1,3);
console.log(buffer2);//<Buffer 65 73>
buffer2[0] = 0;
console.log(buffer1);//<Buffer 74 00 73 74>
console.log(buffer2);//<Buffer 00 73>

【buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]])】

  该措施用于拷贝 buf 的一个区域的数额到 target 的一个区域,固然 target
的内存区域与 buf 的重合

  target <Buffer> | <Uint8Array> 要拷贝进的 Buffer 或
Uint8Array

  targetStart <Integer> target 中起始拷贝进的偏移量。 默许: 0

  sourceStart <Integer> buf 中开头拷贝的偏移量。 当 targetStart
为 undefined 时忽略。 默许: 0

  sourceEnd <Integer> buf 中截止拷贝的偏移量(不带有)。 当
sourceStart 为 undefined 时忽略。 默许: buf.length

  再次来到: <Integer> 被拷贝的字节数

var buffer1 =Buffer.from('test');
var buffer2 = Buffer.alloc(5);
var len = buffer1.copy(buffer2,1,3);
console.log(buffer1);//<Buffer 74 65 73 74>
console.log(buffer2);//<Buffer 00 74 00 00 00>
console.log(len);//1

【buf.compare(target[, targetStart[, targetEnd[, sourceStart[,
sourceEnd]]]])】

  该格局比较 buf 与 target,重返注解 buf 在排序上是或不是排在 target
此前、或将来、或平等。 相比是按照各自 Buffer 实际的字节系列

  target <Buffer> 要比较的 Buffer

  targetStart <Integer> target 中起首对照的偏移量。 默许: 0

  targetEnd <Integer> target 中停止比较的偏移量(不分包)。 当
targetStart 为 undefined 时忽略。 默许: target.length

  sourceStart <Integer> buf 中初露对照的偏移量。 当 targetStart
为 undefined 时忽略。 默许: 0

  sourceEnd <Integer> buf 中截止比较的偏移量(不含有)。 当
targetStart 为 undefined 时忽略。 默许: buf.length

  返回: <Integer>

  如果 target 与 buf 相同,则返回 0 

  如果 target 排在 buf 前面,则返回 1 

  如果 target 排在 buf 后面,则返回 -1 

var buf1 = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9]);
var buf2 = Buffer.from([5, 6, 7, 8, 9, 1, 2, 3, 4]);

// 输出: 0(buf2中的1234对比buf2中的1234)
console.log(buf1.compare(buf2, 5, 9, 0, 4));

// 输出: -1(buf2中的567891对比buf1中的56789)
console.log(buf1.compare(buf2, 0, 6, 4));

// 输出: 1(buf2中的1对比buf2中的6789)
console.log(buf1.compare(buf2, 5, 6, 5));

【buf.equals(otherBuffer)】

  假设 buf 与 otherBuffer 具有完全相同的字节,则赶回 true,否则重临false

  otherBuffer <Buffer> 要比较的 Buffer

  返回: <Boolean>

var buf1 = Buffer.from('ABC');
var buf2 = Buffer.from('ABC');
var buf3 = Buffer.from('abc');
console.log(buf1.equals(buf2));//true
console.log(buf1.equals(buf3));//false

【buf.fill(value[, offset[, end]][, encoding])】

  value <String> | <Buffer> | <Integer> 用来填充 buf
的值

  offset <Integer> 起先填写 buf 的岗位。默许: 0

  end <Integer> 为止填充 buf 的地方(不带有)。默许: buf.length

  encoding <String> 如果 value
是一个字符串,则那是它的字符编码。 默许: ‘utf8’

  返回: <Buffer> buf 的引用

  借使未指定 offset 和 end,则填充整个 buf。
这么些简化使得一个Buffer的开创与填充可以在一行内到位

var b = Buffer.allocUnsafe(10).fill('h');
console.log(b.toString());//hhhhhhhhhh

【buf.indexOf(value[, byteOffset][, encoding])】

  value <String> | <Buffer> | <Integer> 要搜索的值

  byteOffset <Integer> buf 中开端摸索的岗位。默许: 0

  encoding <String> 倘诺 value
是一个字符串,则那是它的字符编码。 默许: ‘utf8’

  再次回到: <Integer> buf 中 value 首次面世的目录,即便 buf 没包罗value 则赶回 -1

  假设value是字符串,则 value 根据 encoding
的字符编码进行解析;即便value是Buffer,则value会被当做一个完完全全应用。若是要相比部分
Buffer 可采纳 buf.slice();假使value是数值,则 value 会解析为一个 0 至
255 之间的无符号八位整数值

var buf = Buffer.from('this is a buffer');

// 输出: 0
console.log(buf.indexOf('this'));

// 输出: 2
console.log(buf.indexOf('is'));

// 输出: 8
console.log(buf.indexOf(Buffer.from('a buffer')));

// 输出: 8
// (97 是 'a' 的十进制 ASCII 值)
console.log(buf.indexOf(97));

// 输出: -1
console.log(buf.indexOf(Buffer.from('a buffer example')));

// 输出: 8
console.log(buf.indexOf(Buffer.from('a buffer example').slice(0, 8)));

【buf.lastIndexOf(value[, byteOffset][, encoding])】

  与 buf.indexOf() 类似,除了 buf 是从后往前寻找而不是从前将来

var buf = Buffer.from('this buffer is a buffer');

// 输出: 0
console.log(buf.lastIndexOf('this'));

// 输出: 17
console.log(buf.lastIndexOf('buffer'));

// 输出: 17
console.log(buf.lastIndexOf(Buffer.from('buffer')));

// 输出: 15
// (97 是 'a' 的十进制 ASCII 值)
console.log(buf.lastIndexOf(97));

// 输出: -1
console.log(buf.lastIndexOf(Buffer.from('yolo')));

// 输出: 5
console.log(buf.lastIndexOf('buffer', 5));

// 输出: -1
console.log(buf.lastIndexOf('buffer', 4));

【buf.includes(value[, byteOffset][, encoding])】

  该措施相当于 buf.indexOf() !== -1

  value <String> | <Buffer> | <Integer> 要搜索的值

  byteOffset <Integer> buf 中初露寻找的职位。默许: 0

  encoding <String> 倘若 value
是一个字符串,则那是它的字符编码。 默许: ‘utf8’

  再次回到: <Boolean> 假诺 buf 找到 value,则赶回 true,否则重返false

var buf = Buffer.from('this is a buffer');

// 输出: true
console.log(buf.includes('this'));

// 输出: true
console.log(buf.includes('is'));

// 输出: true
console.log(buf.includes(Buffer.from('a buffer')));

// 输出: true
// (97 是 'a' 的十进制 ASCII 值)
console.log(buf.includes(97));

// 输出: false
console.log(buf.includes(Buffer.from('a buffer example')));

// 输出: true
console.log(buf.includes(Buffer.from('a buffer example').slice(0, 8)));

// 输出: false
console.log(buf.includes('this', 4));