ホームページ > ウェブフロントエンド > jsチュートリアル > NodeJS_node.jsのBufferモジュールの詳細説明

NodeJS_node.jsのBufferモジュールの詳細説明

WBOY
リリース: 2016-05-16 16:21:34
オリジナル
1642 人が閲覧しました

1、分析を開始します

いわゆるバッファ Buffer は「一時記憶領域」を意味し、入出力データを一時的に保存するメモリのセクションです。

JS 言語自体には文字列データ型のみがあり、バイナリ データ型はありません。そのため、NodeJS はバイナリ データに対する操作を提供する String と同等のグローバル コンストラクター Buffer を提供します。ファイルを読み取ってバッファのインスタンスを取得するだけでなく、次のように直接構築することもできます。

コードをコピーします コードは次のとおりです:
var バッファ = 新しいバッファ([ 0x68, 0x65, 0x6c, 0x6c, 0x6f ]) ;

バッファは文字列に似ています。 .length 属性を使用してバイト長を取得するだけでなく、[index] メソッドを使用して指定された位置のバイトを読み取ることもできます。たとえば、

コードをコピーします コードは次のとおりです:
バッファ[0] ; // 0x68;


バッファと文字列は相互に変換できます。たとえば、指定されたエンコーディングを使用してバイナリ データを文字列に変換できます。

コードをコピーします コードは次のとおりです: var str =buffer.toString("utf-8"); // こんにちは


指定されたエンコーディングで文字列をバイナリ データに変換します:

コードをコピーします コードは次のとおりです: varbuffer= new Buffer("hello", "utf-8") //
;


ちょっとした違い:
バッファと文字列の間には重要な違いがあります。文字列は読み取り専用であり、文字列を変更すると新しい文字列が作成されますが、元の文字列は変更されません。

バッファに関しては、ポインタ操作を実行できる C 言語の配列に似ています。たとえば、[index] メソッドを使用して、特定の位置のバイトを直接変更できます。

----------------------------------------------- --- --------------------------------------------------- --- --------------------------------------------------- --- --------------------------------------------------- -----------------------------------

slice メソッドは、新しいバッファーを返すのではなく、以下に示すように、元のバッファーの中央の位置へのポインターを返します。

[ 0x68、0x65、0x6c、0x6c、0x6f ]

                                                               |

ビン bin.slice(2)

したがって、スライス メソッドによって返されるバッファへの変更は、元のバッファに影響します。例:



コードをコピーします

コードは次のとおりです: varbuffer= 新しいバッファ([ 0x68, 0x65, 0x6c, 0x6c, 0x6f ]) ; var sub = bin.slice(2) ;
sub[0] = 0x65;
console.log(buffer); //



バッファをコピーする場合は、まず新しいバッファを作成し、.copy メソッドを使用して元のバッファ内のデータをコピーする必要があります。
これは、新しいメモリを申請し、既存のメモリ内のデータをコピーすることに似ています。以下に例を示します。

コードをコピーします

コードは次のとおりです: varbuffer= 新しいバッファ([ 0x68, 0x65, 0x6c, 0x6c, 0x6f ]) ; var dup = 新しいバッファ(bin.length) ;
バッファ.コピー(dup) ;
dup[0] = 0x48 ;
console.log(buffer); //
console.log(dup) ; //

つまり、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) 空: ステータスが割り当てられていません

バッファ変換

バッファ オブジェクトは文字列との間で変換できます。サポートされているエンコード タイプは次のとおりです。

ASCII、UTF-8、UTF-16LE/UCS-2、Base64、バイナリ、16 進数

バッファする文字列

新しいバッファ(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.事例の紹介

コードをコピーします コードは次のとおりです:
var buf = new Buffer("これはテキスト連結テストです!") ,str = "これはテキスト連結テストです!" ;
console.time("バッファ連結テスト!");
var list = [] ;
var len = 100000 * buf.length ;
for(var i=0;i List.push(buf) ;
len = buf.length ;
}
var s1 = Buffer.concat(list, len).toString() ;
console.timeEnd("バッファ連結テスト!") ;
console.time("文字列連結テスト!") ;
var list = [] ;
for (var i = 100000; i >= 0; i--) {
List.push(str) ;
}
var s2 = list.join("") ;
console.timeEnd("文字列連結テスト!") ;

結果は次のとおりです:

文字列の読み取り速度は確実に速くなり、バッファーも 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 インスタンスを取得できます。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート