ホームページ  >  記事  >  ウェブフロントエンド  >  ノードのバッファーについて詳しく見る

ノードのバッファーについて詳しく見る

青灯夜游
青灯夜游転載
2023-04-25 19:49:112270ブラウズ

ノードのバッファーについて詳しく見る

ストリームの章の最後で、次のコードによって出力されるチャンクは何なのかという疑問が残ります。

ノードのバッファーについて詳しく見る

印刷してみると、chunk は Buffer オブジェクトであり、その要素は 16 進数の 2 桁の数値、つまり 0 から 255 までの値であることがわかります。 [関連チュートリアルの推奨事項: nodejs ビデオ チュートリアル プログラミング教育 ]

Untitled 1.png

ストリーム内を流れるデータがバッファであることを説明するでは、バッファーの素顔を探ってみましょう!

? なぜ Node に Buffer が導入されたのか?

当初、JS はブラウザ側でのみ動作していました。Unicode でエンコードされた文字列は処理しやすかったのですが、バイナリの場合は非 Unicode エンコーディングの文字列の処理が困難。バイナリはコンピュータの最低レベルのデータ形式であり、ビデオ、オーディオ、プログラム、ネットワークのパケットはすべてバイナリで保存されます。そこで、ノードはバイナリを操作するためのオブジェクトを導入する必要があるため、TCP ストリーム/ファイル システムやバイナリ バイトを処理するその他の操作に使用される Buffer が誕生しました。

Buffer は Node でよく使われるため、Node の起動時に Buffer が導入されており、require() を使用する必要はありません。

ArrayBuffer

何ですか

ArrayBuffer はメモリ内のバイナリ データです。メモリ自体を操作することはできません。TypedArray オブジェクト または DataView を通じて操作する必要があります。バッファ内のデータを特定の形式で表現し、これらの形式を通じてバッファの内容を読み書きします。配列インターフェイスを展開し、配列を使用してデータを操作できます

#TypedArray ビュー

最も一般的に使用されるのは TypeArray ビューで、Uint8Array (符号なし 8 ビット整数) 配列ビュー、Int16Array (16 ビット整数) 配列ビューなどの単純な型の ArrayBuffer の読み取りと書き込みに使用されます

Buffer との関係

NodeJS の Buffer クラスは、実際には Uint8Array の実装です。

バッファ構造

バッファは配列に似たオブジェクトですが、主にバイトの操作に使用されます

モジュール構造

バッファはJSを組み合わせたものですおよび C モジュールのパフォーマンス部分は C で実装され、非パフォーマンス部分は JS で実装されます。

Untitled 2.png

バッファによって占有されるメモリは、V8 によって割り当てられず、オフヒープ メモリに属します。

#オブジェクト構造

Buffer オブジェクトは配列に似ており、その要素は 2 桁の 16 進数、つまり 0 から 255 までの値です

Untitled 3.pngこの例から、異なる文字がバッファ内の異なるバイトを占有することがわかります。UTF-8 エンコーディングでは、中国語は 3 バイトを占有し、英語と半角記号は 1 バイトを占有します。

? 入力要素が 10 進数/負の数/255 を超える場合はどうなりますか?

Untitled 4.png上記の状況の場合、バッファの処理は次のようになります。

要素に割り当てられた値が 0 未満の場合、値は 1 つずつ割り当てられます。0 から 255 までの整数が得られるまで 256 を加算します。
  • 取得した値が 255 より大きい場合は、0 から 255 までの値が得られるまで 256 を 1 つずつ減算します
  • 10 進数の場合、整数部分のみが保持されます。
バッファーに 16 進数が表示されるのはなぜですか

実際には、2 進数はまだメモリに保存されていますが、バッファはメモリを表示しています データは、サイズが 2 バイトの 16 進数の

バッファを使用しています。

00000001 00100011

のように、合計 16 ビットがあります。このように直接表示するのが不便な場合は、16ビットに変換してください Base<buffer></buffer>Bufferの作成

Buffer.allocおよび Buffer.allocUnsafe

固定サイズのバッファを作成

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

  • size 新しいバッファーの必要な長さ
  • fill 新しいバッファーを事前に埋めるために使用される値。デフォルト: 0
  • encoding fill が文字列の場合、これはその文字エンコーディングです。デフォルト値: utf8

Untitled 5.png

Buffer.allocUnsafe(size)

size バイトのバッファを割り当てます。 allocUnsafe は alloc よりも高速に実行されます。 Buffer.allocのように結果は00に初期化されません。

Untitled 6.png

allocUnsafe呼び出し時に割り当てられるメモリセグメントはまだ初期化されていないため、メモリ割り当て速度は非常に遅くなりますが、割り当てられたメモリセグメントには古いデータが含まれている可能性があります。これらの古いデータが使用中に上書きされない場合、メモリ リークが発生する可能性があります。高速ではありますが、使用は避けてください。

Buffer モジュールは、Buffer.poolSize のサイズで内部 Buffer インスタンスを事前に割り当てます。クイック割り当てメモリ プールとして、allocUnsafe を使用して新しいバッファ インスタンスを作成するために使用されます。

Buffer.from

コンテンツに基づいてバッファを直接作成します。

  • Buffer.from( string [, encoding] )
  • Buffer.from(array)
  • Buffer.from(buffer)

Untitled 7.png

#のメモリメカニズムBuffer.allocUnsafe

適用されたメモリを効率的に使用するために、Node.js では動的管理メカニズムである適用前および割り当て後のスラブ機構を採用しています。指定されたサイズは、固定サイズのメモリ領域に適用されます。スラブには次の 3 つの状態があります。

full: 完全に割り当てられた状態
  • partial:部分的に割り当てられた状態
  • 空: 割り当てられていない状態
  • Node.js は、小さなオブジェクトと大きなオブジェクトを区別するために 8 KB を制限として使用します

Untitled 8.png

#バッファ サイズは作成時に決定され、調整することはできません。

小さなオブジェクトを割り当てる

割り当てられたオブジェクトが 8KB 未満の場合、ノードはそれを小さなオブジェクトとして割り当てます

バッファ割り当てプロセスでは、主にローカルの変数プールは中間処理オブジェクトとして機能し、割り当てられた状態のすべてのスラブ ユニットはそれを指します。以下は、新しいスラブ ユニットを割り当てる操作です。これにより、新しく適用された SlowBuffer オブジェクトがそのスラブ ユニットを指します

Untitled 9.pngスラブ ユニット

Untitled 10.png2KB バッファの割り当て

2KB バッファを作成した後、スラブ単位のメモリは次のようになります。

Untitled 11.pngこの割り当てプロセスは実行されます。 by assign メソッドが完了しました

Untitled 12.png2KB バッファを作成した後、現在のスラブ ステータスは部分的です

バッファを再度作成するときに、残りのスラブ ステータスを判断しますスラブサイズ 十分なスペースはありますか?十分な場合は、残りのスペースを使用してスラブ割り当てステータスを更新します

スラブ スペースが十分でない場合は、新しいスラブが構築され、元のスラブの残りのスペースが無駄になります

大きなオブジェクトの割り当て

8KB を超えるバッファがある場合は、直接 creatUnsafeBuffer 関数に進み、スラブ ユニットを割り当てます。このスラブ ユニットは、この大きなバッファ オブジェクトによって排他的に占有されます。

allocate 割り当てメカニズムは図に示すとおりです

バッファのメモリ割り当てメカニズムUntitled 13.png

バッファと文字エンコーディングUntitled 14.png

文字エンコーディング、バッファインスタンス、および JavaScript 文字列間の変換を使用する

#

Node は現在、utf8、ucs2、utf16le、latin1、ascii、base64、hex、base64Url の 8 つのエンコード方式をサポートしています。異なるエンコーディング スキームごとに、一連の API が実装され、異なる結果が返されます。Node.js は、受信したエンコーディングに応じて異なるオブジェクトを返します##バッファと文字列の変換

Convert string to Buffer

Untitled 16.png 主に前述の Buffer.from メソッドを使用し、デフォルトのエンコード方法は utf-8

Buffer to string

? 文字化けが発生するのはなぜですか?この問題を解決するにはどうすればよいでしょうか?

読み取りによると、各読み取りの長さは 4 で、チャンク出力は次のとおりです。

Untitled 17.png

data = chunk の場合
は、

data = data.toString chunk.toString

Untitled 18.pngと同等です。1 つの中国語文字が 3 バイトを占めるため、最初のチャンクの 4 バイト目に文字化けが表示されます。 2 番目のチャンクの 2 番目のバイトはテキストなどを形成できないため、文字化けの問題が表示されます。

ノード関連の詳細については、nodejs チュートリアル を参照してください。

以上がノードのバッファーについて詳しく見るの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。