>  기사  >  웹 프론트엔드  >  Nodejs Buffer 모듈의 공통 API에 대한 자세한 설명

Nodejs Buffer 모듈의 공통 API에 대한 자세한 설명

青灯夜游
青灯夜游앞으로
2021-05-13 10:49:591818검색

이 글에서는 Nodejs 버퍼 모듈의 공통 API에 대해 자세히 소개합니다. 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.

Nodejs Buffer 모듈의 공통 API에 대한 자세한 설명

모듈 개요

Buffer는 노드의 핵심 모듈입니다. 개발자는 이를 사용하여 파일 스트림 읽기 및 쓰기, 네트워크 요청 데이터 처리 등의 바이너리 데이터를 처리할 수 있습니다.

Buffer에는 많은 API가 있습니다. 이 기사에서는 생성, 비교, 연결, 복사, 검색, 순회, 유형 변환, 가로채기, 인코딩 변환 등을 포함하여 더 일반적으로 사용되며 이해하기 쉬운 API만 선택합니다. 버퍼 인스턴스. [추천 학습: "nodejs 튜토리얼"]

Create

  • new Buffer(array)
  • Buffer.alloc(length)
  • Buffer.allocUnsafe(length)
  • Buffer.from(array)

새 버퍼(배열)로

// Creates a new Buffer containing the ASCII bytes of the string 'buffer'
const buf = new Buffer([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]);

확인:

var array = 'buffer'.split('').map(function(v){
    return '0x' + v.charCodeAt(0).toString(16)
});

console.log( array.join() );
// 输出:0x62,0x75,0x66,0x66,0x65,0x72

Buffer.alloc(길이)으로

var buf1 = Buffer.alloc(10);  // 长度为10的buffer,初始值为0x0
var buf2 = Buffer.alloc(10, 1);  // 长度为10的buffer,初始值为0x1
var buf3 = Buffer.allocUnsafe(10);  // 长度为10的buffer,初始值不确定
var buf4 = Buffer.from([1, 2, 3])  // 长度为3的buffer,初始值为 0x01, 0x02, 0x03

By Buffer.from()

예 1: Buffer.from(배열)

르레에

예제 2: Buffer.from(string[, 인코딩])

문자열을 통해 버퍼를 생성합니다. 버퍼를 문자열로 변환할 때 인코딩을 일관되게 유지해야 합니다. 그렇지 않으면 아래와 같이 잘못된 문자가 나타납니다.

// [0x62, 0x75, 0x66, 0x66, 0x65, 0x72] 为字符串 "buffer" 
// 0x62 为16进制,转成十进制就是 98,代表的就是字母 b
var buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]);
console.log(buf.toString());

깨진 문자 분석은 다음과 같습니다.

var buf = Buffer.from('this is a tést');  // 默认采用utf8

// 输出:this is a tést
console.log(buf.toString());  // 默认编码是utf8,所以正常打印

// 输出:this is a tC)st
console.log(buf.toString('ascii'));  // 转成字符串时,编码不是utf8,所以乱码

예제 3: Buffer.from(buffer)

새 Buffer 인스턴스를 생성하고 버퍼 데이터를 새 인스턴스에 복사합니다.

var letter = 'é';
var buff = Buffer.from(letter);  // 默认编码是utf8,这里占据两个字节 <Buffer c3 a9>
var len = buff.length;  // 2
var code = buff[0]; // 第一个字节为0xc3,即195:超出ascii的最大支持范围
var binary = code.toString(2);  // 195的二进制:10101001
var finalBinary = binary.slice(1);  // 将高位的1舍弃,变成:0101001
var finalCode = parseInt(finalBinary, 2);  // 0101001 对应的十进制:67
var finalLetter = String.fromCharCode(finalCode);  // 67对应的字符:C

// 同理 0xa9最终转成的ascii字符为)
// 所以,最终输出为 this is a tC)st

버퍼 비교

buf.equals(otherBuffer)

두 버퍼 인스턴스에 저장된 데이터가 동일한지 확인하면 true를 반환하고, 그렇지 않으면 false를 반환합니다.

var buff = Buffer.from(&#39;buffer&#39;);
var buff2 = Buffer.from(buff);

console.log(buff.toString());  // 输出:buffer
console.log(buff2.toString());  // 输出:buffer

buff2[0] = 0x61;

console.log(buff.toString());  // 输出:buffer
console.log(buff2.toString());  // 输出:auffer

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

는 또한 두 개의 버퍼 인스턴스를 비교합니다. 차이점은 다음과 같습니다.

  • 특정 비교를 지정할 수 있습니다. 범위 (시작 및 끝으로 지정)

  • 반환 값은 정수이며 buf와 대상 간의 크기 관계는 표준

에 도달합니다. 반환 값은

  • 0이라고 가정합니다. >: buf, 대상 크기가 동일합니다. 0:buf、target大小相同。
  • 1:buf大于target,也就是说buf应该排在target之后。
  • -1:buf小于target,也就是说buf应该排在target之前。

看例子,官方的例子挺好的,直接贴一下:

// 例子一:编码一样,内容相同
var buf1 = Buffer.from(&#39;A&#39;);
var buf2 = Buffer.from(&#39;A&#39;);

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

// 例子二:编码一样,内容不同
var buf3 = Buffer.from(&#39;A&#39;);
var buf4 = Buffer.from(&#39;B&#39;);

console.log( buf3.equals(buf4) );  // false

// 例子三:编码不一样,内容相同
var buf5 = Buffer.from(&#39;ABC&#39;);  // <Buffer 41 42 43>
var buf6 = Buffer.from(&#39;414243&#39;, &#39;hex&#39;);

console.log(buf5.equals(buf6));    //true

//只要比较的两者内容相同,`buf.equals(otherBuffer)` 就返回true

Buffer.compare(buf1, buf2)

buf.compare(target) 大同小异,一般用于排序。直接贴官方例子:

const buf1 = Buffer.from(&#39;ABC&#39;);
const buf2 = Buffer.from(&#39;BCD&#39;);
const buf3 = Buffer.from(&#39;ABCD&#39;);

// Prints: 0
console.log(buf1.compare(buf1));

// Prints: -1
console.log(buf1.compare(buf2));

// Prints: -1
console.log(buf1.compare(buf3));

// Prints: 1
console.log(buf2.compare(buf1));

// Prints: 1
console.log(buf2.compare(buf3));

// Prints: [ <Buffer 41 42 43>, <Buffer 41 42 43 44>, <Buffer 42 43 44> ]
// (This result is equal to: [buf1, buf3, buf2])
console.log([buf1, buf2, buf3].sort(Buffer.compare));

从Buffer.from([62])谈起

这里稍微研究下Buffer.from(array)。下面是官方文档对API的说明,也就是说,每个array的元素对应1个字节(8位),取值从0到255。

Allocates a new Buffer using an array of octets.

数组元素为数字

首先看下,传入的元素为数字的场景。下面分别是10进制、8进制、16进制,跟预期中的结果一致。

const buf1 = Buffer.from(&#39;1234&#39;);
const buf2 = Buffer.from(&#39;0123&#39;);
const arr = [buf1, buf2];

// Prints: [ <Buffer 30 31 32 33>, <Buffer 31 32 33 34> ]
// (This result is equal to: [buf2, buf1])
console.log(arr.sort(Buffer.compare));
var buff = Buffer.from([62])
// <Buffer 3e>
// buff[0] === parseInt(&#39;3e&#39;, 16) === 62
var buff = Buffer.from([062])
// <Buffer 32>
// buff[0] === parseInt(62, 8) === parseInt(32, 16) === 50

数组元素为字符串

再看下,传入的元素为字符串的场景。

  • 0开头的字符串,在parseInt('062')时,可以解释为62,也可以解释为50(八进制),这里看到采用了第一种解释。

  • 字符串的场景,跟parseInt()有没有关系,暂未深入探究,只是这样猜想。TODO(找时间研究下)

var buff = Buffer.from([0x62])
// <Buffer 62>
// buff[0] === parseInt(62, 16) === 98
var buff = Buffer.from([&#39;62&#39;])
// <Buffer 3e>
// buff[0] === parseInt(&#39;3e&#39;, 16) === parseInt(&#39;62&#39;) === 62
var buff = Buffer.from([&#39;062&#39;])
// <Buffer 3e>
// buff[0] === parseInt(&#39;3e&#39;, 16) === parseInt(&#39;062&#39;) === 62

数组元素大小超出1个字节

感兴趣的同学自行探究。

var buff = Buffer.from([&#39;0x62&#39;])
// <Buffer 62>
// buff[0] === parseInt(&#39;62&#39;, 16) === parseInt(&#39;0x62&#39;) === 98

Buffer.from('1')

一开始不自觉的会将Buffer.from('1')[0]"1"划等号,其实"1"对应的编码是49。

var buff = Buffer.from([256])
// <Buffer 00>

这样对比就知道了,编码为1的是个控制字符,表示 Start of Heading。

var buff = Buffer.from(&#39;1&#39;)  // <Buffer 31>
console.log(buff[0] === 1)  // false

buffer连接:Buffer.concat(list[, totalLength])

备注:个人觉得totalLength

1: buf는 target보다 큽니다. 즉, buf는 target 다음에 순위가 매겨져야 함을 의미합니다.

-1: buf는 대상보다 작습니다. 이는 buf가 대상보다 먼저 순위가 지정되어야 함을 의미합니다. 🎜🎜🎜예를 보세요. 공식 예는 꽤 좋습니다. 그냥 붙여넣으세요. 🎜
console.log( String.fromCharCode(49) )  // &#39;1&#39;
console.log( String.fromCharCode(1) )  // &#39;\u0001&#39;

🎜Buffer.compare(buf1, buf2)🎜🎜🎜with buf .compare(대상)은 유사하며 일반적으로 정렬에 사용됩니다. 공식 예제를 직접 게시하세요: 🎜
var buff1 = Buffer.alloc(10);
var buff2 = Buffer.alloc(20);

var totalLength = buff1.length + buff2.length;

console.log(totalLength);  // 30

var buff3 = Buffer.concat([buff1, buff2], totalLength);

console.log(buff3.length);  // 30

🎜Buffer.from([62])에 대해 이야기합시다🎜🎜🎜여기서 Buffer.from(array)에 대해 조금 공부해 보겠습니다. 다음은 API에 대한 공식 문서의 설명입니다. 즉, 각 배열 요소는 1바이트(8비트)에 해당하고 값 범위는 0부터 255입니다. 🎜
🎜옥텟 배열을 사용하여 새 버퍼를 할당합니다.🎜

🎜배열 요소는 숫자입니다.🎜🎜🎜먼저 보면 들어오는 요소는 숫자 장면입니다. . 다음은 10진수, 8진수, 16진수이며 예상한 결과와 일치합니다. 🎜
var buff4 = Buffer.from([1, 2]);
var buff5 = Buffer.from([3, 4]);

var buff6 = Buffer.concat([buff4, buff5], 5);

console.log(buff6.length);  // 
console.log(buff6);  // <Buffer 01 02 03 04 00>

var buff7 = Buffer.concat([buff4, buff5], 3);

console.log(buff7.length);  // 3
console.log(buff7);  // <Buffer 01 02 03>
var buff1 = Buffer.from([1, 2]);
var buff2 = Buffer.alloc(2);

buff1.copy(buff2);

console.log(buff2);  // <Buffer 01 02>
const buf1 = Buffer.allocUnsafe(26);
const buf2 = Buffer.allocUnsafe(26).fill(&#39;!&#39;);

for (let i = 0 ; i < 26 ; i++) {
  // 97 is the decimal ASCII value for &#39;a&#39;
  buf1[i] = i + 97;
}

buf1.copy(buf2, 8, 16, 20);

// Prints: !!!!!!!!qrst!!!!!!!!!!!!!
console.log(buf2.toString(&#39;ascii&#39;, 0, 25));

🎜배열 요소가 문자열입니다🎜🎜🎜수신 요소가 문자열인 시나리오를 살펴보겠습니다. 🎜🎜🎜🎜parseInt('062')를 사용하면 0으로 시작하는 문자열은 62 또는 50(8진수)으로 해석될 수 있습니다. 여기서는 첫 번째 해석이 사용되는 것을 볼 수 있습니다. 🎜🎜🎜🎜문자열 시나리오가parseInt()와 관련이 있는지 여부는 아직 깊이 조사되지 않았으며 단지 추측일 뿐입니다. TODO (공부할 시간 찾기)🎜🎜🎜
const buf = Buffer.from(&#39;this is a buffer&#39;);

// Prints: 0
console.log(buf.indexOf(&#39;this&#39;));

// Prints: 2
console.log(buf.indexOf(&#39;is&#39;));

// Prints: 8
console.log(buf.indexOf(Buffer.from(&#39;a buffer&#39;)));

// Prints: 8
// (97 is the decimal ASCII value for &#39;a&#39;)
console.log(buf.indexOf(97));

// Prints: -1
console.log(buf.indexOf(Buffer.from(&#39;a buffer example&#39;)));

// Prints: 8
console.log(buf.indexOf(Buffer.from(&#39;a buffer example&#39;).slice(0, 8)));


const utf16Buffer = Buffer.from(&#39;\u039a\u0391\u03a3\u03a3\u0395&#39;, &#39;ucs2&#39;);

// Prints: 4
console.log(utf16Buffer.indexOf(&#39;\u03a3&#39;, 0, &#39;ucs2&#39;));

// Prints: 6
console.log(utf16Buffer.indexOf(&#39;\u03a3&#39;, -4, &#39;ucs2&#39;));
var buff = Buffer.alloc(4);
buff.write(&#39;a&#39;);  // 返回 1
console.log(buff);  // 打印 <Buffer 61 00 00 00>

buff.write(&#39;ab&#39;);  // 返回 2
console.log(buff);  // 打印 <Buffer 61 62 00 00>
var buff = Buffer.alloc(20).fill(&#39;a&#39;);

console.log(buff.toString());  // aaaaaaaaaaaaaaaaaaaa

🎜배열 요소 크기가 1바이트를 초과했습니다🎜🎜🎜관심 있는 학생들이 스스로 탐색할 수 있습니다. 🎜
var buff = Buffer.from(&#39;hello&#39;);

console.log( buff.toString() );  // hello

console.log( buff.toString(&#39;utf8&#39;, 0, 2) );  // he

🎜Buffer.from('1')🎜🎜🎜무의식적으로 Buffer.from('1')[0]등호 "1"입니다. 실제로 "1"에 해당하는 코드는 49입니다. 🎜
var buff = Buffer.from(&#39;hello&#39;);

console.log( buff.toJSON() );  // { type: &#39;Buffer&#39;, data: [ 104, 101, 108, 108, 111 ] }
🎜이 비교를 통해 코드 1이 제목 시작을 의미하는 제어 문자라는 것을 알 수 있습니다. 🎜
var buff = Buffer.from(&#39;abcde&#39;);

for(const key of buff.keys()){
    console.log(&#39;key is %d&#39;, key);
}
// key is 0
// key is 1
// key is 2
// key is 3
// key is 4

for(const value of buff.values()){
    console.log(&#39;value is %d&#39;, value);
}
// value is 97
// value is 98
// value is 99
// value is 100
// value is 101

for(const pair of buff.entries()){
    console.log(&#39;buff[%d] === %d&#39;, pair[0], pair[1]);
}
// buff[0] === 97
// buff[1] === 98
// buff[2] === 99
// buff[3] === 100
// buff[4] === 101

🎜버퍼 연결: Buffer.concat(list[, totalLength])🎜🎜🎜참고: 개인적으로 totalLength 매개변수는 상당히 중복된다고 생각합니다. 공식문서에 따르면 성능향상 측면에서 고려되고 있다. 그러나 내부 구현에서는 목록을 순회하고 길이를 누적하여 totalLength를 얻습니다. 이러한 관점에서 성능 최적화는 거의 무시할 수 있습니다. 🎜
var buff1 = Buffer.from(&#39;abcde&#39;);
console.log(buff1);  // <Buffer 61 62 63 64 65>

var buff2 = buff1.slice();
console.log(buff2);  // <Buffer 61 62 63 64 65>

var buff3 = buff1.slice(1, 3);
console.log(buff3);  // <Buffer 62 63>

buff3[0] = 97;  // parseInt(61, 16) ==> 97
console.log(buff1);  // <Buffer 62 63>
🎜위에서 언급한 성능 최적화 외에도 totalLength에 대해 주목해야 할 두 가지 사항이 더 있습니다. 목록에 있는 모든 버퍼의 누적 길이가 length라고 가정합니다🎜
  • totalLength > length:返回长度为totalLength的Buffer实例,超出长度的部分填充0。
  • totalLength < length:返回长度为totalLength的Buffer实例,后面部分舍弃。
var buff4 = Buffer.from([1, 2]);
var buff5 = Buffer.from([3, 4]);

var buff6 = Buffer.concat([buff4, buff5], 5);

console.log(buff6.length);  // 
console.log(buff6);  // <Buffer 01 02 03 04 00>

var buff7 = Buffer.concat([buff4, buff5], 3);

console.log(buff7.length);  // 3
console.log(buff7);  // <Buffer 01 02 03>

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

使用比较简单,如果忽略后面三个参数,那就是将buf的数据拷贝到target里去,如下所示:

var buff1 = Buffer.from([1, 2]);
var buff2 = Buffer.alloc(2);

buff1.copy(buff2);

console.log(buff2);  // <Buffer 01 02>

另外三个参数比较直观,直接看官方例子

const buf1 = Buffer.allocUnsafe(26);
const buf2 = Buffer.allocUnsafe(26).fill(&#39;!&#39;);

for (let i = 0 ; i < 26 ; i++) {
  // 97 is the decimal ASCII value for &#39;a&#39;
  buf1[i] = i + 97;
}

buf1.copy(buf2, 8, 16, 20);

// Prints: !!!!!!!!qrst!!!!!!!!!!!!!
console.log(buf2.toString(&#39;ascii&#39;, 0, 25));

查找:buf.indexOf(value[, byteOffset][, encoding])

跟数组的查找差不多,需要注意的是,value可能是String、Buffer、Integer中的任意类型。

  • String:如果是字符串,那么encoding就是其对应的编码,默认是utf8。
  • Buffer:如果是Buffer实例,那么会将value中的完整数据,跟buf进行对比。
  • Integer:如果是数字,那么value会被当做无符号的8位整数,取值范围是0到255。

另外,可以通过byteOffset来指定起始查找位置。

直接上代码,官方例子妥妥的,耐心看完它基本就理解得差不多了。

const buf = Buffer.from(&#39;this is a buffer&#39;);

// Prints: 0
console.log(buf.indexOf(&#39;this&#39;));

// Prints: 2
console.log(buf.indexOf(&#39;is&#39;));

// Prints: 8
console.log(buf.indexOf(Buffer.from(&#39;a buffer&#39;)));

// Prints: 8
// (97 is the decimal ASCII value for &#39;a&#39;)
console.log(buf.indexOf(97));

// Prints: -1
console.log(buf.indexOf(Buffer.from(&#39;a buffer example&#39;)));

// Prints: 8
console.log(buf.indexOf(Buffer.from(&#39;a buffer example&#39;).slice(0, 8)));


const utf16Buffer = Buffer.from(&#39;\u039a\u0391\u03a3\u03a3\u0395&#39;, &#39;ucs2&#39;);

// Prints: 4
console.log(utf16Buffer.indexOf(&#39;\u03a3&#39;, 0, &#39;ucs2&#39;));

// Prints: 6
console.log(utf16Buffer.indexOf(&#39;\u03a3&#39;, -4, &#39;ucs2&#39;));

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

将sring写入buf实例,同时返回写入的字节数。

参数如下:

  • string:写入的字符串。
  • offset:从buf的第几位开始写入,默认是0。
  • length:写入多少个字节,默认是 buf.length - offset。
  • encoding:字符串的编码,默认是utf8。

看个简单例子

var buff = Buffer.alloc(4);
buff.write(&#39;a&#39;);  // 返回 1
console.log(buff);  // 打印 <Buffer 61 00 00 00>

buff.write(&#39;ab&#39;);  // 返回 2
console.log(buff);  // 打印 <Buffer 61 62 00 00>

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

value填充buf,常用于初始化buf。参数说明如下:

  • value:用来填充的内容,可以是Buffer、String或Integer。
  • offset:从第几位开始填充,默认是0。
  • end:停止填充的位置,默认是 buf.length。
  • encoding:如果value是String,那么为value的编码,默认是utf8。

例子:

var buff = Buffer.alloc(20).fill(&#39;a&#39;);

console.log(buff.toString());  // aaaaaaaaaaaaaaaaaaaa

转成字符串: buf.toString([encoding[, start[, end]]])

把buf解码成字符串,用法比较直观,看例子

var buff = Buffer.from(&#39;hello&#39;);

console.log( buff.toString() );  // hello

console.log( buff.toString(&#39;utf8&#39;, 0, 2) );  // he

转成JSON字符串:buf.toJSON()

var buff = Buffer.from(&#39;hello&#39;);

console.log( buff.toJSON() );  // { type: &#39;Buffer&#39;, data: [ 104, 101, 108, 108, 111 ] }

遍历:buf.values()、buf.keys()、buf.entries()

用于对buf进行for...of遍历,直接看例子。

var buff = Buffer.from(&#39;abcde&#39;);

for(const key of buff.keys()){
    console.log(&#39;key is %d&#39;, key);
}
// key is 0
// key is 1
// key is 2
// key is 3
// key is 4

for(const value of buff.values()){
    console.log(&#39;value is %d&#39;, value);
}
// value is 97
// value is 98
// value is 99
// value is 100
// value is 101

for(const pair of buff.entries()){
    console.log(&#39;buff[%d] === %d&#39;, pair[0], pair[1]);
}
// buff[0] === 97
// buff[1] === 98
// buff[2] === 99
// buff[3] === 100
// buff[4] === 101

截取:buf.slice([start[, end]])

用于截取buf,并返回一个新的Buffer实例。需要注意的是,这里返回的Buffer实例,指向的仍然是buf的内存地址,所以对新Buffer实例的修改,也会影响到buf。

var buff1 = Buffer.from(&#39;abcde&#39;);
console.log(buff1);  // <Buffer 61 62 63 64 65>

var buff2 = buff1.slice();
console.log(buff2);  // <Buffer 61 62 63 64 65>

var buff3 = buff1.slice(1, 3);
console.log(buff3);  // <Buffer 62 63>

buff3[0] = 97;  // parseInt(61, 16) ==> 97
console.log(buff1);  // <Buffer 62 63>

TODO

  • 创建、拷贝、截取、转换、查找

  • buffer、arraybuffer、dataview、typedarray

  • buffer vs 编码

  • Buffer.from()、Buffer.alloc()、Buffer.alocUnsafe()

  • Buffer vs TypedArray

文档摘要

关于buffer内存空间的动态分配

Instances of the Buffer class are similar to arrays of integers but correspond to fixed-sized, raw memory allocations outside the V8 heap. The size of the Buffer is established when it is created and cannot be resized.

相关链接

unicode对照表 https://unicode-table.com/cn/#control-character

字符编码笔记:ASCII,Unicode和UTF-8 http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

更多编程相关知识,请访问:编程视频!!

위 내용은 Nodejs Buffer 모듈의 공통 API에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제