Node.js Buffer对象详解:创建、内存管理与常用方法
本文深入解析Node.js中的Buffer对象,涵盖从ES6 TypedArray引入前的背景到现代API的演变。详细讲解Buffer的创建方式(alloc、allocUnsafe、from)、底层内存管理策略(slab分配与8KB阈值),以及字符串转换、类方法与实例方法的完整使用指南,帮助开发者高效处理二进制数据。
Node.js Buffer对象概述
前言
在ES6引入TypedArray之前,JavaScript语言缺乏读取或操作二进制数据流的机制。Buffer类作为Node.js API的一部分被引入,旨在处理TCP流和文件系统操作等场景中的二进制数据。尽管ES6已添加TypedArray,但Buffer类以更适合Node.js用例的方式实现了Uint8Array。本文将详细介绍Buffer对象。
概述
Node.js应用常需处理网络协议、数据库操作、图片处理及文件上传等场景,涉及大量二进制数据。JavaScript原生字符串无法满足这些需求,因此Buffer对象应运而生。
Buffer是一个典型的JavaScript与C++结合模块,性能相关部分由C++实现,非性能部分由JavaScript实现。Buffer实例类似整数数组,但大小固定且在V8堆外分配物理内存。其大小在创建时确定,不可调整。
由于Buffer使用频繁,Node.js在进程启动时已加载并将其置于全局对象(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);
Buffer对象的创建方式
创建
在Node.js v6之前,Buffer实例通过Buffer构造函数创建,根据参数返回不同Buffer。新版本Node.js提供了对应的新方法。
1、new Buffer(size)。传入数值作为第一个参数(如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的类数组特性
类数组
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>
如果要访问其对应的字符,则需要使用字符串的fromCharCode()方法。
console.log(String.fromCharCode(buf[0]));//'m'
Buffer内存管理机制
内存分配
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与字符串的转换
转换
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类方法与实例方法
类方法
【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));
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
Java和JavaScript的应用场景分工:后端企业级开发与Web前端交互
2026-11-05 15:57:34
除了浏览器和Node.js,还有哪些轻量级Js脚本运行工具?
2026-11-04 17:38:24
无需后端:用JavaScript实现简单网站的本地数据存储
2026-11-03 23:03:30
Node.js 下载慢或官网打不开怎么办
2026-11-03 18:19:37
JS解析大体积Excel文件内存溢出怎么办
2026-11-03 18:19:37
