Node.js 버퍼 사용법에 대한 자세한 설명

php中世界最好的语言
풀어 주다: 2018-05-28 15:40:06
원래의
1939명이 탐색했습니다.

이번에는 Node.jsBuffer 사용법에 대해 자세히 설명하고, Node.js Buffer 사용 시 주의사항은 무엇인지 살펴보겠습니다.

버퍼란 무엇인가요?

Buffer는 전역 개체로 존재하므로 모듈을 도입하지 않고도 사용할 수 있습니다. 절대 무시할 수 없습니다.

버퍼는 바이너리 데이터를 저장하기 위해 메모리에 오픈된 영역이라고 이해하시면 됩니다. 버퍼는 오프힙 메모리를 엽니다.

Buffer의 적용 시나리오는 무엇입니까?

흐름을 어떻게 이해하나요? 스트림은 데이터의 모음(데이터 및 문자열과 유사)이지만 스트림의 데이터를 한 번에 가져올 수 없으며 데이터가 모두 메모리에 로드되지 않습니다. 따라서 스트림은 매우 적합합니다. 간헐적으로 청크를 반환하는 빅 데이터 처리 및 외부 소스. 스트림 생산자와 소비자 사이의 속도는 일반적으로 일관되지 않으므로 일부 데이터를 임시로 저장하려면 버퍼가 필요합니다. 버퍼 크기는 highWaterMark 매개변수로 지정되며 기본적으로 16Kb입니다.

많은 메모리가 필요한 데이터 저장

Buffer 객체가 차지하는 메모리 공간은 Node.js 프로세스의 메모리 공간 제한에 포함되지 않으므로 큰 객체를 저장하는 데 사용할 수 있지만 크기는 개체의 범위는 여전히 제한되어 있습니다. 일반적으로 32비트 시스템은 1G 정도, 64비트 시스템은 2G 정도입니다.

버퍼 생성 방법

스트림에 의한 자동 및 암시적 버퍼 생성 외에도 다음과 같이 수동으로 버퍼를 생성할 수도 있습니다.

버퍼에 저장된 데이터가 결정되었습니다.

Buffer.from(obj) // Obj는 문자열, 버퍼, arrayBuffer, 배열 또는 배열 유사 객체 유형을 지원합니다

참고: Buffer.from은 아래와 같이 숫자 전달을 지원하지 않습니다.

Buffer.from(1234);
buffer.js:208
  throw new errors.TypeError(
  ^
TypeError [ERR_INVALID_ARG_TYPE]: The "value" argument must not be of type number. Received type number
  at Function.from (buffer.js:208:11)
  ...
로그인 후 복사

숫자를 전달하려면 배열을 전달하면 됩니다. :

const buf = Buffer.from([1, 2, 3, 4]);
console.log(buf); // <Buffer 01 02 03 04>
로그인 후 복사

하지만 이 방법에는 문제가 있습니다. 다른 값이 저장되면 아래와 같이 버퍼에 기록된 바이너리 데이터가 동일해집니다.

const buf2 = Buffer.from([127, -1]);
console.log(buf2);   // <Buffer 7f ff>
const buf3 = Buffer.from([127, 255]);
console.log(buf3);  // <Buffer 7f ff>
console.log(buf3.equals(buf2)); // true
로그인 후 복사

기록할 숫자 집합이 모두 0에서 255(읽기의 경우 readUInt8) 사이에 있거나 모두 -128 ~ 127(읽기의 경우 readInt8) 범위에 속하면 문제가 없습니다. 그렇지 않으면 Buffer.from을 사용하여 숫자 집합을 저장하는 것은 권장되지 않습니다. 왜냐하면 다른 숫자를 읽을 때 다른 메서드를 호출해야 하기 때문입니다.

버퍼 저장 데이터가 결정되지 않았습니다

Buffer.alloc, Buffer.allocUnsafe, Buffer.allocUnsafeSlow

Buffer.alloc은 할당된 메모리를 0 값으로 채우므로 후자보다 속도가 느립니다. 또한 더 안전합니다. 물론 --zero-fill-buffers 플래그를 사용하여 메모리 할당 후 allocUnsafe 및 allocUnsafeSlow를 0 값으로 채울 수도 있습니다.

node --zero-fill-buffers index.js
로그인 후 복사

할당된 공간이 4KB 미만인 경우 allocUnsafe는 이전에 미리 할당된 버퍼에서 공간을 직접 분할하므로 할당된 공간이 4KB 이상인 경우 속도는 allocUnsafeSlow보다 빠릅니다. 둘 사이의 속도.

// 分配空间等于4KB
function createBuffer(fn, size) {
 console.time('buf-' + fn);
 for (var i = 0; i < 100000; i++) {
  Buffer[fn](size);
 }
 console.timeEnd(&#39;buf-&#39; + fn);
}
createBuffer(&#39;alloc&#39;, 4096);
createBuffer(&#39;allocUnsafe&#39;, 4096);
createBuffer(&#39;allocUnsafeSlow&#39;, 4096);
// 输出
buf-alloc:      294.002ms
buf-allocUnsafe:   224.072ms
buf-allocUnsafeSlow: 209.22ms
로그인 후 복사
function createBuffer(fn, size) {
 console.time(&#39;buf-&#39; + fn);
 for (var i = 0; i < 100000; i++) {
  Buffer[fn](size);
 }
 console.timeEnd(&#39;buf-&#39; + fn);
}
createBuffer(&#39;alloc&#39;, 4095);
createBuffer(&#39;allocUnsafe&#39;, 4095);
createBuffer(&#39;allocUnsafeSlow&#39;, 4095);
// 输出
buf-alloc:      296.965ms
buf-allocUnsafe:   135.877ms
buf-allocUnsafeSlow: 205.225ms
로그인 후 복사

한 가지 기억해야 할 점: 새로운 Buffer(xxxx) 메서드는 더 이상 권장되지 않습니다

Buffer

buffer to string

const buf = Buffer.from(&#39;test&#39;);
console.log(buf.toString(&#39;utf8&#39;));         // test
console.log(buf.toString(&#39;utf8&#39;, 0, 2));      // te
로그인 후 복사

buffer to json

const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]);
console.log(buf.toJSON());  // { type: &#39;Buffer&#39;, data: [ 1, 2, 3, 4, 5 ] }
로그인 후 복사

buffer cut, 는 자르기 후 반환된 새 버퍼는 원래 버퍼와 동일한 메모리

buf.slice([start[, end]])
로그인 후 복사
  1. 시작 시작 위치

  2. 끝 끝 위치(포함되지 않음)

예:

var buf1 = Buffer.from(&#39;test&#39;);
var buf2 = buf1.slice(1, 3).fill(&#39;xx&#39;);
console.log("buf2 content: " + buf2.toString()); // xx
console.log("buf1 content: " + buf1.toString()); // txxt
로그인 후 복사

버퍼 복사, 버퍼 및 배열 다름 , 버퍼의 길이는 일단 결정되면 변하지 않으므로 복사된 원본 버퍼가 대상 버퍼보다 ​​큰 경우 값의 일부만 복사됩니다

buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]])
로그인 후 복사

예:

var buf1 = Buffer.from(&#39;abcdefghijkl&#39;);
var buf2 = Buffer.from(&#39;ABCDEF&#39;);
buf1.copy(buf2, 1);
console.log(buf2.toString()); //Abcdef
로그인 후 복사

버퍼 동등성 판단, 비교 는 이진 값입니다

buf.equals(otherBuffer)
로그인 후 복사

예:

const buf1 = Buffer.from(&#39;ABC&#39;);
const buf2 = Buffer.from(&#39;414243&#39;, &#39;hex&#39;); 
console.log(buf1.equals(buf2));  // true
로그인 후 복사

같음 외에도 비교를 사용하여 두 값이 같은지 여부를 확인할 수도 있지만(결과가 0이면 같음) 비교의 주요 기능은 정렬하는 것입니다. 배열의 버퍼 인스턴스.

버퍼에 특정 값이 포함되어 있는지 여부

buf.includes(value[, byteOffset][, encoding])
buf.indexOf(value[, byteOffset][, encoding])
로그인 후 복사

示例:

const buf = Buffer.from(&#39;this is a buffer&#39;);
console.log(buf.includes(&#39;this&#39;)); // true
console.log(buf.indexOf(&#39;this&#39;)); // 0
로그인 후 복사

写入读取数值

写入方法:

位数固定且超过1个字节的: write{Double| Float | Int16 | Int32| UInt16 | UInt32 }{BE|LE}(value, offset)

位数不固定的: write{Int | UInt}{BE | LE}(value, offset, bytelength) //此方法提供了更灵活的位数表示数据(比如3位、5位)

位数固定是1个字节的: write{Int8 | Unit8}(value, offset)

读取方法:

位数固定且超过1个字节的: read{Double| Float | Int16 | Int32 | UInt16 | UInt32 }{BE|LE}(offset)

位数不固定的: read{Int | UInt}{BE | LE}(offset, byteLength)

位数固定是1个字节的: read{Int8 | Unit8}(offset)

Double、Float、Int16、Int32、UInt16、UInt32既确定了表征数字的位数,也确定了是否包含负数,因此定义了不同的数据范围。同时由于表征数字的位数都超过8位,无法用一个字节来表示,因此就涉及到了计算机的字节序区分(大端字节序与小端字节序)

关于大端小端的区别可以这么理解:数值的高位在buffer的起始位置的是大端,数值的低位buffer的起始位置则是小端

const buf = Buffer.allocUnsafe(2);
buf.writeInt16BE(256, 0) 
console.log(buf);      // <Buffer 01 00> 
buf.writeInt16LE(256, 0)
console.log(buf);      // <Buffer 00 01>
로그인 후 복사

http://tools.jb51.net/transcoding/hexconvert这里可以查看数值的不同进制之间的转换,如果是大端的话,则直接按顺序(0100)拼接16进制即可,如果是小端则需要调换一下顺序才是正确的表示方式。

buffer合并

Buffer.concat(list[, totalLength]) //totalLength不是必须的,如果不提供的话会为了计算totalLength会多一次遍历

const buf1 = Buffer.from('this is');
const buf2 = Buffer.from(' funny');
console.log(Buffer.concat([buf1, buf2], buf1.length + buf2.length));
// <Buffer 74 68 69 73 20 69 73 20 66 75 6e 6e 79>
로그인 후 복사

清空buffer

清空buffer数据最快的办法是buffer.fill(0)

buffer模块与Buffer的关系

Buffer是全局global上的一个引用,指向的其实是buffer.Buffer

 const buffer = require('buffer');
 console.log(buffer.Buffer === Buffer); //true
로그인 후 복사

buffer模块上还有其他一些属性和方法

const buffer = require('buffer');
console.log(buffer);
{ Buffer:
  { [Function: Buffer]
   poolSize: 8192,
   from: [Function: from],
   alloc: [Function: alloc],
   allocUnsafe: [Function: allocUnsafe],
   allocUnsafeSlow: [Function: allocUnsafeSlow],
   isBuffer: [Function: isBuffer],
   compare: [Function: compare],
   isEncoding: [Function: isEncoding],
   concat: [Function: concat],
   byteLength: [Function: byteLength],
   [Symbol(node.isEncoding)]: [Function: isEncoding] },
 SlowBuffer: [Function: SlowBuffer],
 transcode: [Function: transcode],
 INSPECT_MAX_BYTES: 50,
 kMaxLength: 2147483647,
 kStringMaxLength: 1073741799,
 constants: { MAX_LENGTH: 2147483647, MAX_STRING_LENGTH: 1073741799 } }
로그인 후 복사

上面的kMaxLength与MAX_LENGTH代表了新建buffer时内存大小的最大值,当超过限制值后就会报错

32为机器上是(2^30)-1(~1GB)

64位机器上是(2^31)-1(~2GB)

Buffer释放

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

如何搭建React全家桶环境

怎样使用JS实现调用本地摄像头

위 내용은 Node.js 버퍼 사용법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!