Node.js API详解之 Buffer
在 ECMAScript 2015 (ES6) 引入 TypedArray 之前,JavaScript 语言没有读取或操作二进制数据流的机制。
Buffer 类被引入作为 Node.js API 的一部分,使其可以在 TCP 流或文件系统操作等场景中处理二进制数据流。
TypedArray 现已被添加进 ES6 中,Buffer 类以一种更优化、更适合 Node.js 用例的方式实现了 Uint8Array API。
Buffer 类的实例类似于整数数组,但 Buffer 的大小是固定的、且在 V8 堆外分配物理内存。 Buffer 的大小在被创建时确定,且无法调整。
Buffer 类在 Node.js 中是一个全局变量,因此无需使用 require(‘buffer’).Buffer。

目录:

Buffer类:

buffer实例

buffer模块

Buffer 与字符编码

说明:

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 编码。当从字符串创建 Buffer 时,按照 RFC4648 第 5 章的规定,这种编码也将正确地接受“URL 与文件名安全字母表”。

‘latin1’ – 一种把 Buffer 编码成一字节编码的字符串的方式(由 IANA 定义在 RFC1345 第 63 页,用作 Latin-1 补充块与 C0/C1 控制码)。

‘binary’ – ‘latin1’ 的别名。

‘hex’ – 将每个字节编码为两个十六进制字符。

demo:

const buf = Buffer.from('hello isjs', 'utf8');

console.log(buf.toString('hex'));
//68656c6c6f2069736a73
console.log(buf.toString('ascii'));
//hello isjs
console.log(buf.toString('utf8'));
//hello isjs
console.log(buf.toString('utf16le'));
//敨汬獩獪
console.log(buf.toString('ucs2'));
//敨汬獩獪
console.log(buf.toString('base64'));
//aGVsbG8gaXNqcw==
console.log(buf.toString('latin1'));
//hello isjs
console.log(buf.toString('binary'));
//hello isjs

Buffer 与 ES6 迭代器

说明:

Buffer 实例可以使用 ECMAScript 2015 (ES6) 的 for..of 语法进行遍历。

demo:

const buf = Buffer.from('isjs', 'utf8');

for(let b of buf){
	console.log(b)
}
// 105
// 115
// 106
// 115

new Buffer()

说明:

在 Node.js v6 之前的版本中,Buffer 实例是通过 Buffer 构造函数创建的,它根据提供的参数返回不同的 Buffer。
在下面的demo中为大家详细的介绍

demo:

// 传一个数值作为第一个参数给 Buffer()(如 new Buffer(10)),则分配一个指定大小的新建的 Buffer 对象。 
// 在 Node.js 8.0.0 之前,分配给这种 Buffer 实例的内存是没有初始化的,且可能包含敏感数据。 
// 这种 Buffer 实例随后必须被初始化,可以使用 buf.fill(0) 或写满这个 Buffer。 
// 从 Node.js 8.0.0 开始, Buffer(num) 和 new Buffer(num) 将返回一个初始化内存之后的 Buffer。
var bufferArr = new Buffer(5);

console.log(bufferArr);//<Buffer 00 00 00 00 00>

// 传一个字符串、数组、或 Buffer 作为第一个参数,则将所传对象的数据拷贝到 Buffer 中。
bufferArr = new Buffer('isjs.cn');

console.log(bufferArr);//<Buffer 69 73 6a 73 2e 63 6e>

bufferArr = new Buffer([0x69,0x73,0x6a,0x73]);

console.log(bufferArr);//<Buffer 69 73 6a 73>

Buffer.poolSize

说明:

该属性用于决定预分配的、内部 Buffer 实例池的大小的字节数。 这个值可以修改。默认: 8192

demo:

console.log(Buffer.poolSize);
//8192

Buffer.from(string[, encoding])

说明:

新建一个包含所给的 JavaScript 字符串 string 的 Buffer 。
encoding: 指定 string 的字符编码。

demo:

var buffer = Buffer.from('isjs.cn');

console.log(buffer);
//<Buffer 69 73 6a 73 2e 63 6e>
console.log(buffer.toString());
//isjs.cn

buffer = Buffer.from('7468697320697320612074c3a97374', 'hex');

console.log(buffer);
//<Buffer 74 68 69 73 20 69 73 20 61 20 74 c3 a9 73 74>
console.log(buffer.toString());
//this is a tést

Buffer.from(array)

说明:

通过一个八位字节的 array 创建一个新的 Buffer

demo:

var buffer = Buffer.from([0x69, 0x73, 0x6a, 0x73, 0x2e, 0x63, 0x6e]);

console.log(buffer);
//<Buffer 69 73 6a 73 2e 63 6e>

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

说明:

该方法将创建一个 ArrayBuffer 的视图,而不会复制底层内存。
arrayBuffer: 一个 ArrayBuffer,或一个 TypedArray 的 .buffer 属性。
byteOffset:开始拷贝的索引。默认为 0。
length: 拷贝的字节数。默认为 arrayBuffer.length – byteOffset。

demo:

const arr = new Uint16Array(2);

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

const 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.from(buffer)

说明:

将传入的 buffer 数据拷贝到一个新建的 Buffer 实例。

demo:

const buf1 = Buffer.from('isjs.cn');
const buf2 = Buffer.from(buf1);

buf1[0] = 0x61;

// 输出: auffer
console.log(buf1);
//<Buffer 61 73 6a 73 2e 63 6e>

// 输出: buffer
console.log(buf2);
//<Buffer 69 73 6a 73 2e 63 6e>

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

说明:

为了使 Buffer 实例的创建更可靠、更不容易出错,各种 new Buffer() 构造函数已被 废弃,
并由 Buffer.from()、Buffer.alloc()、和 Buffer.allocUnsafe() 方法替代
Buffer.alloc(): 返回一个指定大小的被填满的 Buffer 实例。
这个方法会明显地比 Buffer.allocUnsafe(size) 慢,
但可确保新创建的 Buffer 实例绝不会包含旧的和潜在的敏感数据。
size: 新建的 Buffer 期望的长度
fill: 用来预填充新建的 Buffer 的值。 默认: 0
encoding: 如果 fill 是字符串,则该值是它的字符编码。 默认: ‘utf8’

demo:

var buffer = Buffer.alloc(10);

console.log(buffer);
//<Buffer 00 00 00 00 00 00 00 00 00 00>

//创建一个长度为 10、且用 0x1 填充的 Buffer。 
buffer = Buffer.alloc(10, 1);

console.log(buffer);
//<Buffer 01 01 01 01 01 01 01 01 01 01>

Buffer.allocUnsafe(size)

说明:

分配一个大小为 size 字节的新建的 Buffer 。
以这种方式创建的 Buffer 实例的底层内存是未初始化的。 新创建的 Buffer 的内容是未知的,且可能包含敏感数据。
可以使用 buf.fill(0) 初始化 Buffer 实例为0。

demo:

const buf = Buffer.allocUnsafe(10);

console.log(buf);
//<Buffer 07 00 00 00 00 00 00 00 08 00>

buf.fill(0);

console.log(buf);
//<Buffer 00 00 00 00 00 00 00 00 00 00>

Buffer.allocUnsafeSlow(size)

说明:

分配一个大小为 size 字节的新建的 Buffer
以这种方式创建的 Buffer 实例的底层内存是未初始化的。
当使用 Buffer.allocUnsafe() 分配新建的 Buffer 时,当分配的内存小于 4KB 时,默认会从一个单一的预分配的 Buffer 切割出来。
这使得应用程序可以避免垃圾回收机制因创建太多独立分配的 Buffer 实例而过度使用。
这个方法通过像大多数持久对象一样消除追踪与清理的需求,改善了性能与内存使用。
在开发者可能需要在不确定的时间段从内存池保留一小块内存的情况下,使用 Buffer.allocUnsafeSlow() 创建一个非池的 Buffer 实例然后拷贝出相关的位元是合适的做法。

demo:

const buf = Buffer.allocUnsafeSlow(10);

console.log(buf);
//<Buffer 00 00 00 00 00 00 00 00 1a 00>

buf.fill(0);

console.log(buf);
//<Buffer 00 00 00 00 00 00 00 00 00 00>

alloc与allocUnsafe,allocUnsafeSlow比较

1.安全性

当调用 Buffer.allocUnsafe() 和 Buffer.allocUnsafeSlow() 时,被分配的内存段是未初始化的(没有用 0 填充)。
虽然这样的设计使得内存的分配非常快,但已分配的内存段可能包含潜在的敏感旧数据。
使用通过 Buffer.allocUnsafe() 创建的没有被完全重写内存的 Buffer ,在 Buffer 内存可读的情况下,可能泄露它的旧数据。
虽然使用 Buffer.allocUnsafe() 有明显的性能优势,但必须额外小心,以避免给应用程序引入安全漏洞

2.存储位置

Buffer 模块会预分配一个大小为 Buffer.poolSize 的内部 Buffer 实例作为快速分配池,
用于使用 Buffer.allocUnsafe() 新创建的 Buffer 实例,以及废弃的 new Buffer(size) 构造器,
仅限于当 size 小于或等于 Buffer.poolSize >> 1 (Buffer.poolSize 除以2后的最大整数值)。
对这个预分配的内部内存池的使用,是调用 Buffer.alloc(size, fill) 和 Buffer.allocUnsafe(size).fill(fill) 的关键区别。
具体地说,Buffer.alloc(size, fill) 永远不会使用这个内部的 Buffer 池,
但如果 size 小于或等于 Buffer.poolSize 的一半, Buffer.allocUnsafe(size).fill(fill) 会使用这个内部的 Buffer 池。
当应用程序需要 Buffer.allocUnsafe() 提供额外的性能时,这个细微的区别是非常重要的。

3.如何选择

首先从安全角度考虑是采用alloc还是allocUnsafe。
性能方面,因为alloc多做了一步fill(),所以较慢。
如果buffer创建频繁,或未知时间的持久化,且数据量小于4kb,建议采用allocUnsafeSlow,避免了buffer实例的过度创建,从而浪费性能。

Buffer.byteLength(string[, encoding])

说明:

返回一个字符串的实际字节长度。 这与 String.prototype.length 不同,因为那返回字符串的字符数。
string: 要计算长度的值
encoding: 如果 string 是字符串,则这是它的字符编码。 默认: ‘utf8’

demo:

const testStr = '我是isjs.cn';

const testStrLen = testStr.length;

const testStrCharLen =  Buffer.byteLength(testStr);


console.log(`${testStr}: ${testStrLen}个字符,${testStrCharLen}个字节`);
//我是isjs.cn: 9个字符,13个字节

console.log(Buffer.from(testStr));
//<Buffer e6 88 91 e6 98 af 69 73 6a 73 2e 63 6e>

Buffer.compare(buf1, buf2)

说明:

基于各自 Buffer 实际的字节序列,比较 buf1 和 buf2 ,通常用于 Buffer 实例数组的排序。
如果 buf2 与 buf1 相同,则返回 0 。
如果 buf2 排在 buf1 前面,则返回 1 。
如果 buf2 排在 buf1 后面,则返回 -1 。

demo:

const buf1 = Buffer.from('1');
const buf2 = Buffer.from('2');

console.log( Buffer.compare(buf1, buf2) );
//-1

Buffer.concat(list[, totalLength])

说明:

返回一个合并了 list 中所有 Buffer 实例的新建的 Buffer 。
如果 list 中没有元素、或 totalLength 为 0 ,则返回一个新建的长度为 0 的 Buffer 。
如果没有提供 totalLength ,则从 list 中的 Buffer 实例计算得到。
为了计算 totalLength 会导致需要执行额外的循环,所以提供明确的长度会运行更快。
如果提供了 totalLength,totalLength 必须是一个正整数。
如果从 list 中计算得到的 Buffer 长度超过了 totalLength,则合并的结果将会被截断为 totalLength 的长度。

demo:

const buf1 = Buffer.from('1');
const buf2 = Buffer.from('22');
const buf3 = Buffer.from('333');

const totalLength = buf1.length + buf2.length + buf3.length;

console.log(totalLength);
//6

const bufA = Buffer.concat([buf1, buf2, buf3], totalLength);

console.log(bufA);
//<Buffer 31 32 32 33 33 33>

console.log(bufA.length);
//6

Buffer.isBuffer(obj)

说明:

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

demo:

const buf1 = Buffer.from('1');

console.log(Buffer.isBuffer(buf1));
//true

console.log(Buffer.isBuffer('123'));
//false

Buffer.isEncoding(encoding)

说明:

如果 encoding 是一个支持的字符编码则返回 true,否则返回 false 。

demo:

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

console.log(Buffer.isEncoding('utf9'));
//false

buf.buffer

说明:

buffer 属性指向创建该 Buffer 的底层的 ArrayBuffer 对象。

demo:

const testBuffer = Buffer.from('isjs.cn');

console.log(testBuffer.buffer);
//ArrayBuffer { byteLength: 8192 }

buf.length

说明:

返回 buf 在字节数上分配的内存量。 注意,这并不一定反映 buf 内可用的数据量
虽然 length 属性可以进行修改,但改变 length 的值可能会导致不确定、不一致的行为。
那些希望修改一个 Buffer 的长度的应用程序应当将 length 视为只读的。
需要对 Buffer 长度进行修改时,建议使用 buf.slice() 创建一个新的 Buffer。

demo:

const buf = Buffer.from('isjs');

console.log(buf.length);
// 4

buf.write('some string', 0, 'ascii');

console.log(buf.length);
// 4

buf[index]

说明:

索引操作符 [index] 可用于获取或设置 buf 中指定 index 位置的八位字节。
这个值指向的是单个字节,所以合法的值范围是的 0x00 至 0xFF(十六进制),或 0 至 255(十进制)。

demo:

const testBuffer = Buffer.from('isjs.cn');

console.log(testBuffer[1]);
//115

testBuffer[1] =  0x74;

console.log(testBuffer.toString());
//itjs.cn

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

说明:

target: 要比较的 Buffer 或 Uint8Array。
targetStart: target 中开始对比的偏移量。 默认: 0
targetEnd: target 中结束对比的偏移量(不包含)。 默认: target.length
sourceStart: uf 中开始对比的偏移量。 默认: 0
sourceEnd: buf 中结束对比的偏移量(不包含)。 默认: buf.length
比较 buf 与 target,返回表明 buf 在排序上是否排在 target 之前、或之后、或相同。 对比是基于各自 Buffer 实际的字节序列。
如果 target 与 buf 相同,则返回 0 。
如果 target 排在 buf 前面,则返回 1 。
如果 target 排在 buf 后面,则返回 -1 。

demo:

const buf1 = Buffer.from('1');
const buf2 = Buffer.from('2');
const buf3 = Buffer.from('3');


console.log(buf2.compare(buf1));
//1
console.log(buf2.compare(buf2));
//0
console.log(buf2.compare(buf3));
//-1

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

说明:

拷贝 buf 的一个区域的数据到 target 的一个区域,即便 target 的内存区域与 buf 的重叠。
target: 要拷贝进的 Buffer 或 Uint8Array。
targetStart: target 中开始拷贝进的偏移量。 默认: 0
sourceStart: buf 中开始拷贝的偏移量。 默认: 0
sourceEnd: buf 中结束拷贝的偏移量(不包含)。 默认: buf.length
返回被拷贝的字节数。

demo:

const buf1 = Buffer.from('123456789');
const buf2 = Buffer.from('****');

buf2.copy(buf1, 4, 0); 

console.log(buf1.toString());
//1234****9

buf.entries()

说明:

从 buf 的内容中,创建并返回一个 [index, byte] 形式的迭代器。

demo:

const buf = Buffer.from('buffer');

for (const pair of buf.entries()) {
  console.log(pair);
}
//   [0, 98]
//   [1, 117]
//   [2, 102]
//   [3, 102]
//   [4, 101]
//   [5, 114]

buf.equals(otherBuffer)

说明:

如果 buf 与 otherBuffer 具有完全相同的字节,则返回 true,否则返回 false。

demo:

const buf1 = Buffer.from('buffer');
const buf2 = Buffer.from('isjs');

console.log(buf1.equals(buf1));
// true
console.log(buf1.equals(buf2));
// false

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

说明:

对buf进行填充。
value: 用来填充 buf 的值。
offset: 开始填充 buf 前要跳过的字节数。默认: 0。
end: 结束填充 buf 的位置(不包含)。默认: buf.length。
encoding: 如果 value 是一个字符串,则这是它的字符编码。默认: ‘utf8’。

demo:

const buf = Buffer.allocUnsafe(10).fill('a');
const buf1 = Buffer.allocUnsafe(10).fill(71);
const buf2 = Buffer.allocUnsafe(10).fill(0x71);

console.log(buf);
//<Buffer 61 61 61 61 61 61 61 61 61 61>
console.log(buf1.toString());
//GGGGGGGGGG
console.log(buf2.toString());
//qqqqqqqqqq

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

说明:

检索 buf 中 value 首次出现的位置。
value:要搜索的值
byteOffset: buf 中开始搜索的位置。默认: 0
encoding: 如果 value 是一个字符串,则这是它的字符编码。 默认: ‘utf8’
返回 buf 中 value 首次出现的索引,如果 buf 没包含 value 则返回 -1

demo:

const buf = Buffer.from('this is a isjs');

console.log(buf.indexOf('isjs'));
// 10

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

说明:

检索 buf 中 value 最后出现的位置。
value: 要搜索的值
byteOffset: buf 中开始搜索的位置。 默认: buf.length- 1
encoding:如果 value 是一个字符串,则这是它的字符编码。 默认: ‘utf8’
返回 buf 中 value 最后一次出现的索引,如果 buf 没包含 value 则返回 -1

demo:

const buf = Buffer.from('this is a isjs');

console.log(buf.lastIndexOf('i'));
// 10

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

说明:

从buf中查找指定内容。
value: 要搜索的值
byteOffset: buf 中开始搜索的位置。默认: 0
encoding:如果 value 是一个字符串,则这是它的字符编码。 默认: ‘utf8’
如果 buf 找到 value,则返回 true,否则返回 false

demo:

const buf = Buffer.from('this is a isjs');

console.log(buf.includes('isjs'));
// true

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

说明:

返回一个指向相同原始内存的新建的 Buffer,但做了偏移且通过 start 和 end 索引进行裁剪。
start: 新建的 Buffer 开始的位置。 默认: 0
end: 新建的 Buffer 结束的位置(不包含)。 默认: buf.length
注意,修改这个新建的 Buffer 切片,也会同时修改原始的 Buffer 的内存,因为这两个对象所分配的内存是重叠的。

demo:

const buf1 = Buffer.from('this is a isjs');

const buf2 = buf1.slice(10);

console.log(buf2);
//<Buffer 69 73 6a 73>

buf1[10] = 'a';

console.log(buf2);
//<Buffer 00 73 6a 73>

// 指定负的索引会导致切片的生成是相对于 buf 的末尾而不是开头。
const buf3 = buf1.slice(-4);


const buf4 = buf1.slice(-4, -2);

console.log(buf3);
//<Buffer 00 73 6a 73>

console.log(buf4);
//<Buffer 00 73>

buf.keys()

说明:

创建并返回一个包含 buf 键名(索引)的迭代器

demo:

const buf = Buffer.from('isjs');

console.log(buf);
//<Buffer 62 75 66 66 65 72>

for (const key of buf.keys()) {
  console.log(key);
}
// 0
// 1
// 2
// 3

buf.values()

说明:

创建并返回一个包含 buf 的值(字节)的迭代器。
当 Buffer 使用 for..of 时会自动调用该函数。

demo:

const buf = Buffer.from('isjs');

for (const value of buf.values()) {
  console.log(value);
}
// 105
// 115
// 106
// 115

for (const value of buf) {
  console.log(value);
}
// 105
// 115
// 106
// 115

buf.toJSON()

说明:

返回 buf 的 JSON 格式。 当字符串化一个 Buffer 实例时,JSON.stringify() 会隐式地调用该函数。

demo:

const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]);

console.log(buf.toJSON());
//{ type: 'Buffer', data: [ 1, 2, 3, 4, 5, 6, 7, 8 ] }

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

说明:

根据 encoding 指定的字符编码解码 buf 成一个字符串。 start 和 end 可传入用于只解码 buf 的一部分。
encoding: 解码使用的字符编码。默认: ‘utf8’
start: 开始解码的字节偏移量。默认: 0
end: 结束解码的字节偏移量(不包含)。 默认: buf.length
字符串实例的最大长度(以UTF-16代码为单位)可查看buffer.constants.MAX_STRING_LENGTH。

demo:

const buf = Buffer.from('isjs.cn');

console.log(buf.toString());
//isjs.cn

buf.swap16()

说明:

将 buf 解析为一个无符号16位的整数数组,并且以字节顺序原地进行交换。
如果 buf.length 不是2的倍数,则抛出 RangeError 错误。

demo:

const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]);
 
console.log(buf1);
//<Buffer 01 02 03 04 05 06 07 08>

buf1.swap16();

console.log(buf1);
//<Buffer 02 01 04 03 06 05 08 07>

const buf2 = Buffer.from([0x1, 0x2, 0x3]);

buf2.swap16();
//抛出异常: RangeError: Buffer size must be a multiple of 16-bits

buf.swap32()

说明:

将 buf 解析为一个无符号32位的整数数组,并且以字节顺序原地进行交换。
如果 buf.length 不是4的倍数,则抛出 RangeError 错误。

demo:

const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]);

console.log(buf1);
//<Buffer 01 02 03 04 05 06 07 08>

buf1.swap32();

console.log(buf1);
//<Buffer 04 03 02 01 08 07 06 05>

const buf2 = Buffer.from([0x1, 0x2, 0x3]);

buf2.swap32();
// 抛出异常: RangeError: Buffer size must be a multiple of 32-bits

buf.swap64()

说明:

将 buf 解析为一个64位的数值数组,并且以字节顺序原地进行交换。
如果 buf.length 不是8的倍数,则抛出 RangeError 错误。

demo:

const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]);

console.log(buf1);
//<Buffer 01 02 03 04 05 06 07 08>

buf1.swap64();

console.log(buf1);
//<Buffer 08 07 06 05 04 03 02 01>

const buf2 = Buffer.from([0x1, 0x2, 0x3]);

buf2.swap64();
// 抛出异常: RangeError: Buffer size must be a multiple of 64-bits

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

说明:

根据 encoding 的字符编码写入 string 到 buf 中的 offset 位置。
length 参数是写入的字节数。
如果 buf 没有足够的空间保存整个字符串,则只会写入 string 的一部分。 只部分解码的字符不会被写入。

demo:

const buf = Buffer.alloc(20);

const len = buf.write('this is a isjs', 3, 10, 'utf8');

console.log(buf);
//<Buffer 00 00 00 74 68 69 73 20 69 73 20 61 20 00 00 00 00 00 00 00>

console.log(`${len} 个字节: ${buf.toString('utf8', 0, len)}`);
// 10 个字节: this is

buf.writeIntBE(value, offset, byteLength[, noAssert])(大端)

buf.writeIntLE(value, offset, byteLength[, noAssert])(小端)

说明:

写入 value 中的 byteLength 个字节到 buf 中指定的 offset 位置。
最高支持48位精度。 当 value 不是一个有符号的整数时,反应是不确定的。
设置 noAssert 为 true 则 value 的编码形式可超出 buf 的末尾,但后果是不确定的。
value: 要写入 buf 的数值。
offset: 开始写入前要跳过的字节数,必须满足:0 <= offset <= buf.length - byteLength。 byteLength: 要写入的字节数,必须满足:0 < byteLength <= 6。 noAssert: 是否跳过 value、offset 和 byteLength 检验?默认: false。

demo:

const buf = Buffer.allocUnsafe(6);

buf.writeIntBE(0x1234567890ab, 0, 6);

console.log(buf);
//<Buffer 12 34 56 78 90 ab>

buf.writeIntLE(0x1234567890ab, 0, 6);

console.log(buf);
//<Buffer ab 90 78 56 34 12>

buf.writeInt8(value, offset[, noAssert])

说明:

写入 value 到 buf 中指定的 offset 位置。
value 应当是一个有效的有符号的8位整数。 当 value 不是一个有符号的8位整数时,反应是不确定的。
设置 noAssert 为 true 则 value 的编码形式可超出 buf 的末尾,但后果是不确定的。
value 会被解析并写入为二进制补码值。

demo:

const buf = Buffer.allocUnsafe(2);

buf.writeInt8(2, 0);
buf.writeInt8(-2, 1);

console.log(buf);
// 输出: <Buffer 02 fe>

buf.writeInt16BE(value, offset[, noAssert])

buf.writeInt16LE(value, offset[, noAssert])

说明:

value 应当是一个有效的有符号的16位整数。

demo:

const buf = Buffer.allocUnsafe(4);

buf.writeInt16BE(0x0102, 0);
buf.writeInt16LE(0x0304, 2);

console.log(buf);
// 输出: <Buffer 01 02 04 03>

buf.writeInt32BE(value, offset[, noAssert])

buf.writeInt32LE(value, offset[, noAssert])

说明:

value 应当是一个有效的有符号的32位整数。

demo:

const buf = Buffer.allocUnsafe(8);

buf.writeInt32BE(0x01020304, 0);
buf.writeInt32LE(0x05060708, 4);

console.log(buf);
// 输出: <Buffer 01 02 03 04 08 07 06 05>

buf.writeUIntBE(value, offset, byteLength[, noAssert])

buf.writeUIntLE(value, offset, byteLength[, noAssert])

说明:

写入 value 中的 byteLength 个字节到 buf 中指定的 offset 位置。
最高支持48位精度。 当 value 不是一个有符号的整数时,反应是不确定的。
设置 noAssert 为 true 则 value 的编码形式可超出 buf 的末尾,但后果是不确定的。
value: 要写入 buf 的数值。
offset: 开始写入前要跳过的字节数,必须满足:0 <= offset <= buf.length - byteLength。 byteLength: 要写入的字节数,必须满足:0 < byteLength <= 6。 noAssert: 是否跳过 value、offset 和 byteLength 检验?默认: false。

demo:

const buf = Buffer.allocUnsafe(6);

buf.writeUIntBE(0x1234567890ab, 0, 6);

console.log(buf);
// 输出: <Buffer 12 34 56 78 90 ab>

buf.writeUIntLE(0x1234567890ab, 0, 6);

console.log(buf);
// 输出: <Buffer ab 90 78 56 34 12>

buf.writeUInt8(value, offset[, noAssert])

说明:

写入 value 到 buf 中指定的 offset 位置。
value 应当是一个有效的有符号的8位整数。 当 value 不是一个有符号的8位整数时,反应是不确定的。
设置 noAssert 为 true 则 value 的编码形式可超出 buf 的末尾,但后果是不确定的。
value 会被解析并写入为二进制补码值。

demo:

const buf = Buffer.allocUnsafe(4);

buf.writeUInt8(0x3, 0);
buf.writeUInt8(0x4, 1);
buf.writeUInt8(0x23, 2);
buf.writeUInt8(0x42, 3);

// 输出: <Buffer 03 04 23 42>
console.log(buf);

buf.writeUInt16BE(value, offset[, noAssert])

buf.writeUInt16LE(value, offset[, noAssert])

说明:

value 应当是一个有效的无符号的16位整数。

demo:

const buf = Buffer.allocUnsafe(4);

buf.writeUInt16BE(0xdead, 0);
buf.writeUInt16BE(0xbeef, 2);

console.log(buf);
// 输出: <Buffer de ad be ef>

buf.writeUInt16LE(0xdead, 0);
buf.writeUInt16LE(0xbeef, 2);

console.log(buf);
// 输出: <Buffer ad de ef be>

buf.writeUInt32BE(value, offset[, noAssert])

buf.writeUInt32LE(value, offset[, noAssert])

说明:

value 应当是一个有效的无符号的32位整数。

demo:

const buf = Buffer.allocUnsafe(4);

buf.writeUInt32BE(0xfeedface, 0);

console.log(buf);
// 输出: <Buffer fe ed fa ce>

buf.writeUInt32LE(0xfeedface, 0);

console.log(buf);
// 输出: <Buffer ce fa ed fe>

buf.writeFloatBE(value, offset[, noAssert])

buf.writeFloatLE(value, offset[, noAssert])

说明:

value 应当是一个有效的32位浮点值

demo:

const buf = Buffer.allocUnsafe(4);

buf.writeFloatBE(0xcafebabe, 0);

console.log(buf);
// 输出: <Buffer 4f 4a fe bb>

buf.writeFloatLE(0xcafebabe, 0);

console.log(buf);
// 输出: <Buffer bb fe 4a 4f>

buf.writeDoubleBE(value, offset[, noAssert])

buf.writeDoubleLE(value, offset[, noAssert])

说明:

value 应当是一个有效的64位双精度值。

demo:

const buf = Buffer.allocUnsafe(8);

buf.writeDoubleBE(0xdeadbeefcafebabe, 0);

console.log(buf);
// 输出: <Buffer 43 eb d5 b7 dd f9 5f d7>

buf.writeDoubleLE(0xdeadbeefcafebabe, 0);

console.log(buf);
// 输出: <Buffer d7 5f f9 dd b7 d5 eb 43>

buf.readIntBE(offset, byteLength[, noAssert])

buf.readIntLE(offset, byteLength[, noAssert])

说明:

从 buf 中指定的 offset 读取 byteLength 个字节,且读取的值会被解析为二进制补码值。 最高支持48位精度。
设置 noAssert 为 true 则 offset 可超出 buf 的最后一位字节,但后果是不确定的。

demo:

const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]);

console.log(buf.readIntLE(0, 6).toString(16));
// 输出: -546f87a9cbee

console.log(buf.readIntBE(0, 6).toString(16));
// 输出: 1234567890ab

console.log(buf.readIntBE(1, 6).toString(16));
// 抛出异常: RangeError: Index out of range

buf.readInt8(offset[, noAssert])

说明:

从 buf 中指定的 offset 读取一个有符号的8位整数值。

demo:

const buf = Buffer.from([-1, 5]);

console.log(buf.readInt8(0));
// 输出: -1

console.log(buf.readInt8(1));
// 输出: 5

console.log(buf.readInt8(2));
// 抛出异常: RangeError: Index out of range

buf.readInt16BE(offset[, noAssert])

buf.readInt16LE(offset[, noAssert])

说明:

从 buf 中指定的 offset 读取一个有符号的16位整数值。

demo:

const buf = Buffer.from([0, 5]);

console.log(buf.readInt16BE());
// 输出: 5

console.log(buf.readInt16LE());
// 输出: 1280

console.log(buf.readInt16LE(1));
// 抛出异常: RangeError: Index out of range

buf.readInt32BE(offset[, noAssert])

buf.readInt32LE(offset[, noAssert])

说明:

从 buf 中指定的 offset 读取一个有符号的32位整数值。

demo:

const buf = Buffer.from([0, 0, 0, 5]);

console.log(buf.readInt32BE());
// 输出: 5

console.log(buf.readInt32LE());
// 输出: 83886080

console.log(buf.readInt32LE(1));
// 抛出异常: RangeError: Index out of range

buf.readUIntBE(offset, byteLength[, noAssert])

buf.readUIntLE(offset, byteLength[, noAssert])

说明:

从 buf 中指定的 offset 读取 byteLength 个字节,且读取的值会被解析为无符号的整数。 最高支持48位精度。
设置 noAssert 为 true 则 offset 可超出 buf 的最后一位字节,但后果是不确定的。

demo:

const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]);

console.log(buf.readUIntBE(0, 6).toString(16));
// 输出: 1234567890ab

console.log(buf.readUIntLE(0, 6).toString(16));
// 输出: ab9078563412

console.log(buf.readUIntBE(1, 6).toString(16));
//抛出异常: RangeError: Index out of range

buf.readUInt8(offset[, noAssert])

说明:

从 buf 中指定的 offset 读取一个无符号的8位整数值。

demo:

const buf = Buffer.from([1, -2]);

console.log(buf.readUInt8(0));
// 输出: 1

console.log(buf.readUInt8(1));
// 输出: 254

console.log(buf.readUInt8(2));
// 抛出异常: RangeError: Index out of range

buf.readUInt16BE(offset[, noAssert])

buf.readUInt16LE(offset[, noAssert])

说明:

从 buf 中指定的 offset 读取一个无符号的16位整数值。

demo:

const buf = Buffer.from([0x12, 0x34, 0x56]);

// 输出: 1234
console.log(buf.readUInt16BE(0).toString(16));

// 输出: 3412
console.log(buf.readUInt16LE(0).toString(16));

// 输出: 3456
console.log(buf.readUInt16BE(1).toString(16));

// 输出: 5634
console.log(buf.readUInt16LE(1).toString(16));

// 抛出异常: RangeError: Index out of range
console.log(buf.readUInt16LE(2).toString(16));

buf.readUInt32BE(offset[, noAssert])

buf.readUInt32LE(offset[, noAssert])

说明:

从 buf 中指定的 offset 读取一个无符号的32位整数值

demo:

const buf = Buffer.from([0x12, 0x34, 0x56, 0x78]);

console.log(buf.readUInt32BE(0).toString(16));
// 输出: 12345678

console.log(buf.readUInt32LE(0).toString(16));
// 输出: 78563412

console.log(buf.readUInt32LE(1).toString(16));
// 抛出异常: RangeError: Index out of range

bbuf.readFloatBE(offset[, noAssert])

b

buf.readFloatLE(offset[, noAssert])

说明:

从 buf 中指定的 offset 读取一个32位浮点值。

demo:

const buf = Buffer.from([1, 2, 3, 4]);

console.log(buf.readFloatBE());
// 输出: 2.387939260590663e-38
console.log(buf.readFloatLE());
// 输出: 1.539989614439558e-36

console.log(buf.readFloatLE(1));
// 抛出异常: RangeError: Index out of range


console.log(buf.readFloatLE(1, true));
// 警告: 读取超出 buffer 的最后一位字节!
// 这会导致内存区段错误!不要这么做!

bbuf.readDoubleBE(offset[, noAssert])

b

buf.readDoubleLE(offset[, noAssert])

说明:

从 buf 中指定的 offset 读取一个64位双精度值。

demo:

const buf = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]);

console.log(buf.readDoubleBE());
// 输出: 8.20788039913184e-304

console.log(buf.readDoubleLE());
// 输出: 5.447603722011605e-270

console.log(buf.readDoubleLE(1));
// 抛出异常: RangeError: Index out of range

console.log(buf.readDoubleLE(1, true));
// 警告: 读取超出 buffer 的最后一位字节!
// 这会导致内存区段错误!不要这么做!

buffer模块

说明:

除了全局的Buffer之外,也可以通过require(‘buffer’)来引用buffer模块。
buffer模块是通过require(‘buffer’)返回的,而不是全局Buffer或Buffer实例。

buffer.INSPECT_MAX_BYTES

说明:

当调用 buf.inspect() 时返回的最大字节数。 可以被用户模块重写。

demo:

const buffer = require('buffer');

console.log(buffer.INSPECT_MAX_BYTES);
//50

buffer.transcode(source, fromEnc, toEnc)

说明:

将给定的 Buffer 或 Uint8Array 实例从一个字符编码重新编码到另一个字符。 返回一个新的Buffer实例。
source:一个 Buffer 或 Uint8Array 实例
fromEnc: 当前编码
toEnc: 目标编码
如果 fromEnc 或 toEnc 指定的字符串编码无效,或者不允许从 fromEnc 转换为 toEnc,将抛出异常。
如果给定的字节序列不能在目标编码中充分表示,转码过程将使用替代字符。

demo:

const buffer = require('buffer');

const newBuf = buffer.transcode(Buffer.from('isjs€'), 'utf8', 'ascii');
console.log(newBuf.toString('ascii'));
// isjs?

buffer.constants.MAX_LENGTH

说明:

返回单个Buffer实例允许的最大量度
在32位体系结构上,这个值是(2^30)-1 (~1GB)。 在64位体系结构上,这个值是(2^31)-1 (~2GB)。

demo:

const buffer = require('buffer');

console.log(buffer.constants.MAX_LENGTH);
//268435440

buffer.constants.MAX_STRING_LENGTH

说明:

单个string实例允许的最大长度。
代表string能有的原始最大长度,以UTF-16代码为单位。该值可能取决于正在使用的JS引擎。

demo:

const buffer = require('buffer');

console.log(buffer.constants.MAX_STRING_LENGTH);
//268435440