ホームページ  >  記事  >  ウェブフロントエンド  >  Node.jsのバッファ使用方法の詳細な説明

Node.jsのバッファ使用方法の詳細な説明

php中世界最好的语言
php中世界最好的语言オリジナル
2018-05-28 15:40:061955ブラウズ

今回は、Node.jsBufferの使い方と、Node.js Bufferを使用する際の注意事項について詳しく説明します。以下は実際のケースですので、見てみましょう。

バッファとは何ですか?

Buffer はグローバルオブジェクトとして存在しており、モジュールを導入せずに使用することができます。絶対に無視することはできません。

バッファとは、バイナリデータを格納するためにメモリ上に開かれた領域であることが理解できます。バッファーはオフヒープ メモリを解放します。

Buffer の応用シナリオは何ですか?

流れ

流れをどのように理解しますか?ストリームはデータの集合です (データや文字列と同様) が、ストリームのデータは一度に取得できず、すべてのデータがメモリにロードされるわけではないため、ストリームは次の用途に非常に適しています。ビッグ データ処理と断続的にチャンクを返す外部ソース。ストリームのプロデューサーとコンシューマー間の速度は通常一貫していないため、一部のデータを一時的に保存するためにバッファーが必要になります。バッファ サイズは highWaterMark パラメータで指定されます。デフォルトでは 16Kb です。

大量のメモリを必要とするデータの保存

Buffer オブジェクトが占有するメモリ空間は、Node.js プロセスのメモリ空間制限にカウントされないため、大きなオブジェクトの格納に使用できますが、サイズはオブジェクトの数はまだ限られています。一般に、32 ビット システムは約 1G、64 ビット システムは約 2G です。

バッファの作成方法

ストリームによるバッファの自動および暗黙的な作成に加えて、次のように手動でバッファを作成することもできます:

バッファに格納されるデータは決定されています

Buffer.from(obj) // Obj は、string、buffer、arrayBuffer、array、または配列のようなオブジェクトの型をサポートします

注: 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>

記録される数値のセットがすべて 0 ~ 255 (読み取りには readUInt8) の範囲内に収まる場合、またはすべてが -128 ~ 127 (読み取りには readInt8) の範囲内に収まる場合は問題ありません。それ以外の場合は、一連の数値を保存するために Buffer.from を使用することは強くお勧めできません。異なる数値を読み取る場合は、異なるメソッドを呼び出す必要があるためです。

バッファストレージデータは未定ですBuffer.alloc、Buffer.allocUnsafe、Buffer.allocUnsafeSlow

Buffer.allocは割り当てられたメモリを0の値で埋めるため、後者2つよりも遅くなります。より安全でもあります。もちろん、 --zero-fill-buffers フラグを使用して、メモリを割り当てた後に allocUnsafe および allocUnsafeSlow をゼロ値で埋めることもできます。

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

割り当てられたスペースが 4KB 未満の場合、allocUnsafe は事前に割り当てられたバッファーからスペースを直接スライスするため、割り当てられたスペースが 4KB 以上の場合は、allocUnsafeSlow よりも速度が速くなります。二人の間のスピードにおいて。

node --zero-fill-buffers index.js
// 分配空间等于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

覚えておくべきこと: 新しい Buffer(xxxx) メソッドは推奨されなくなりました

Buffer を使用してください

buffer to string

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 to json

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のトリミング後に返される新しいバッファは、元のバッファと同じメモリを指します

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

    start開始位置
  1. end終了位置(含まれていません)
  2. 例:
buf.slice([start[, end]])

バッファのコピー、バッファおよび配列 異なる, バッファの長さは一度決まると変わらないので、コピー元のバッファがターゲットのバッファより大きい場合は値の一部のみがコピーされます

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)

等しいことに加えて、比較はそれらが等しいかどうかを判断するためにも使用できます(結果が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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。