1、分析を開始します
いわゆるバッファ Buffer は「一時記憶領域」を意味し、入出力データを一時的に保存するメモリのセクションです。
JS 言語自体には文字列データ型のみがあり、バイナリ データ型はありません。そのため、NodeJS はバイナリ データに対する操作を提供する String と同等のグローバル コンストラクター Buffer を提供します。ファイルを読み取ってバッファのインスタンスを取得するだけでなく、次のように直接構築することもできます。
バッファに関しては、ポインタ操作を実行できる C 言語の配列に似ています。たとえば、[index] メソッドを使用して、特定の位置のバイトを直接変更できます。
----------------------------------------------- --- --------------------------------------------------- --- --------------------------------------------------- --- --------------------------------------------------- -----------------------------------
slice メソッドは、新しいバッファーを返すのではなく、以下に示すように、元のバッファーの中央の位置へのポインターを返します。
[ 0x68、0x65、0x6c、0x6c、0x6f ]
|
ビン bin.slice(2)
したがって、スライス メソッドによって返されるバッファへの変更は、元のバッファに影響します。例:
コードをコピーします
コードをコピーします
つまり、Buffer は JS のデータ処理機能を文字列から任意のバイナリ データまで拡張します。
上記は、Buffer とは何かについての簡単な紹介です。次に、その使用方法と具体的な使用シナリオについて説明します。
2、バッファについて話しましょう
JavaScript は文字列処理に非常に適しており、ワイドバイト文字列でもシングルバイト文字列でも文字列とみなされます。ノードは、ネットワーク プロトコルの処理、データベースの操作、画像の処理、ファイルのアップロードなどを行う必要があります。また、大量のバイナリ データを処理する必要もあります。そのため、組み込みの文字列ではこれらの要件を満たしていないため、Buffer が登場しました。
バッファ構造
BufferはJavaScriptとCを組み合わせた代表的なモジュールです。性能に関わる部分はCで実装され、性能に関係ない部分はJavaScriptで実装されます。
プロセスの開始時にノードはすでにバッファをメモリにロードし、それをグローバル オブジェクトに配置しているため、requireする必要はありません
バッファ オブジェクト: 配列と同様、その要素は 2 桁の 16 進数です。
バッファメモリ割り当て
Buffer オブジェクトのメモリ割り当ては V8 のヒープ メモリにありません。メモリ アプリケーションは Node の C レベルで実装されます。
要求されたメモリを効率的に使用するために、Node はスラブ割り当てメカニズムを採用しています。スラブは、さまざまな *nix オペレーティング システムを適用する動的メモリ管理メカニズムです。スラブには 3 つの状態があります:
(1) full: 完全に割り当てられた状態
(2) パーシャル: 部分割り当てステータス
(3) 空: ステータスが割り当てられていません
バッファ変換
バッファ オブジェクトは文字列との間で変換できます。サポートされているエンコード タイプは次のとおりです。
バッファする文字列
新しいバッファ(str, [エンコーディング])、デフォルトの UTF-8
buf.write(文字列, [オフセット], [長さ], [エンコーディング])
文字列へのバッファ
buf.toString([エンコーディング], [開始], [終了])バッファーでサポートされていないエンコード タイプ
Buffer.isEncoding(encoding) でサポートされているかどうかを判断します
iconv-lite: 純粋な JavaScript 実装、軽量、C から JavaScript への変換を行わないパフォーマンスの向上
iconv: C の libiconv ライブラリを呼び出して完了します
バッファスプライシング
「res.on('data', function(chunk) {})」に注意してください。パラメータ chunk は、ワイドバイト文字の場合、自動的に文字列に変換されます。 、が生成される可能性があります。
解決策:
(1) このメソッドは、読み取り可能なストリームの setEncoding() メソッドを通じて、データ イベントを Buffer オブジェクトとしてではなく、内部で StringEncoder モジュールを使用するエンコードされた文字列として送信できるようにします。(2) Buffer オブジェクトを配列に一時的に格納し、最終的にそれを大きな Buffer に組み立ててから、出力用の文字列にエンコードします。
バッファはファイル I/O やネットワーク I/O で広く使用されており、そのパフォーマンスは非常に重要であり、通常の文字列よりもはるかに優れています。
文字列の変換時のパフォーマンスの低下に加えて、Buffer の使用にはファイル読み取り時のパフォーマンスにとって重要な highWaterMark 設定があります。
a. highWaterMark 設定は、バッファ メモリの割り当てと使用に一定の影響を与えます。
b. highWaterMark の設定が小さすぎると、システムコールが多すぎる可能性があります。
バッファを使用する場合と使用しない場合 ------ 純粋な JavaScript は Unicode コードをサポートしますが、TCP ストリームまたはファイル ストリームを扱う場合、非ストリームを保存するときに処理する必要があります。 utf-8 文字列、バイナリ、その他の形式の場合は、「バッファ」を使用する必要があります。
3.事例の紹介
結果は次のとおりです:
文字列の読み取り速度は確実に速くなり、バッファーも toString() 操作が必要になります。 したがって、文字列を保存するときは、大きな文字列が文字列に結合された場合でも、バッファより遅くなることはありません。
それでは、バッファを再度使用する必要があるのはいつでしょうか?他に方法がない場合、非 utf-8 文字列、バイナリ、その他の形式を保存する場合は、これを使用する必要があります。
4、まとめ
(1)、JavaScript は Unicode でエンコードされたデータの処理には適していますが、バイナリ データの処理には適していません。
(2) したがって、TCP ストリームまたはファイル システムを処理する場合は、オクテット ストリームを処理する必要があります。
(3)、ノードには、オクテット ストリームを処理、作成、消費するためのメソッドがいくつかあります。
(4) 元のデータは Buffer インスタンスに格納されます。Buffer は整数配列に似ていますが、そのメモリは V8 スタックの外部に割り当てられます。バッファのサイズは変更できません。
(5)、処理されるエンコーディング タイプは、ascii、utf8、utf16le、ucs2 (utf16le のエイリアス)、base64、バイナリ、16 進です。
(6)、Buffer はグローバル要素であり、new Buffer() を使用して直接 Buffer インスタンスを取得できます。