目次
指定された Buffer
Buffer的拼接
encoding
Buffer与性能
ホームページ ウェブフロントエンド jsチュートリアル Node.js の Buffer モジュールを簡単に理解する

Node.js の Buffer モジュールを簡単に理解する

Nov 24, 2021 pm 07:20 PM
buffer node.js

この記事では、Node.js のバッファを理解し、バッファ構造、バッファ メモリ割り当て、バッファ スプライシングなどについて説明します。皆さんのお役に立てれば幸いです。

Node.js の Buffer モジュールを簡単に理解する

#バッファについて理解する

JavaScript文字列操作に非常に適しています

# Buffer

Array のようなオブジェクトで、主にバイトの操作に使用されます。

バッファ構造

Buffer

は、JavaScript と C を組み合わせた代表的なモジュールです。パフォーマンスに関連する部分は C で実装され、それ以外の部分は C で実装されます。パフォーマンス関連の部分は C で実装されています。一部は JavaScript で実装されています。

Node.js の Buffer モジュールを簡単に理解する#Buffer によって占有されるメモリは V8 を通じて割り当てられず、オフヒープ メモリに属します。 V8 ガベージ コレクションはパフォーマンスに影響を与えるため、より効率的で独自のメモリ割り当てとリサイクル ポリシーを使用して、一般的に使用される操作オブジェクトを管理することをお勧めします。

バッファは、ノード プロセスの開始時にすでに値が設定されており、グローバル オブジェクト (グローバル) に配置されます。

Buffer オブジェクト

Buffer オブジェクトの要素は 2 桁の 16 進数ではなく、つまり、0 ~ 255

let buf01 = Buffer.alloc(8);
console.log(buf01);  // <Buffer 00 00 00 00 00 00 00 00>
ログイン後にコピー

の値です。

fill

を使用して buf の値を埋めることができます (デフォルトは utf-8 エンコードです)。値がバッファを超えると、書き込まれません。

バッファ長がコンテンツより大きい場合、バッファは繰り返し埋められます。

以前に埋められたコンテンツをクリアしたい場合は、直接
fill を実行できます。 ()

<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>buf01.fill(&amp;#39;12345678910&amp;#39;) console.log(buf01); // &lt;Buffer 31 32 33 34 35 36 37 38&gt; console.log(buf01.toString()); // 12345678</pre><div class="contentsignin">ログイン後にコピー</div></div>記入内容が中国語の場合、

utf-8

の影響で、3要素に漢字が入り、文字と半角句読点が入ります。 1要素を占有します。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>let buf02 = Buffer.alloc(18, &amp;#39;开始我们的新路程&amp;#39;, &amp;#39;utf-8&amp;#39;); console.log(buf02.toString()); // 开始我们的新</pre><div class="contentsignin">ログイン後にコピー</div></div>

Buffer

Array type によって大きく影響されます。長さ属性にアクセスして長さを取得したり、添字を使用して要素にアクセスしたりすることもできます。また、indexOf を通じて要素の位置を表示することもできます。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>console.log(buf02); // &lt;Buffer e5 bc 80 e5 a7 8b e6 88 91 e4 bb ac e7 9a 84 e6 96 b0&gt; console.log(buf02.length) // 18字节 console.log(buf02[6]) // 230: e6 转换后就是 230 console.log(buf02.indexOf(&amp;#39;我&amp;#39;)) // 6:在第7个字节位置 console.log(buf02.slice(6, 9).toString()) // 我: 取得&lt;Buffer e6 88 91&gt;,转换后就是&amp;#39;我&amp;#39;</pre><div class="contentsignin">ログイン後にコピー</div></div>バイトに割り当てられた値が 0

255 までの整数ではない場合、または割り当てられた値が 10 進数の場合、割り当てられた値が 0 より小さい場合は、値に 256 を 1 つずつ加算していきます。 0

255 の整数の間の値を取得します。 255 より大きい場合は、255 を 1 つずつ減算します。小数の場合は、小数部分を切り捨てます (四捨五入なし)

バッファ メモリ割り当て

バッファ

オブジェクトのメモリ割り当ては、 V8 ヒープ内 メモリ内では、メモリ アプリケーションはノードの C レベルで実装されます。大量のバイト データを処理する場合、メモリが必要なときにオペレーティング システムからメモリを申請できないためです。このため、Node は C レベルのメモリを使用して JavaScript

Node

スラブ割り当てメカニズムを採用します, slab は動的メモリ管理メカニズムであり、現在 Linuxslab などの一部の

*nix

オペレーティング システムで広く使用されています。スラブには次の 3 つの状態があります:

full: 完全に割り当てられた状態
  • partial: 部分的な割り当てステータス
  • empty: 割り当てられていないステータス
  • ノードは、バッファがラージ オブジェクトかスモール オブジェクトかを区別するための制限として
8KB

を使用します。

console.log(Buffer.poolSize);  // 8192
ログイン後にコピー

この 8KB の値は各スラブのサイズです。JavaScript レベルでは、メモリ割り当ての単位として使用されます

#小さなバッファ オブジェクトを割り当てます

指定された Buffer

サイズが 8KB 未満の場合、ノードはスモール オブジェクト メソッド

に従ってサイズを割り当てます。新しいスラブ ユニットを構築します。スラブは現在空の状態です。

Node.js の Buffer モジュールを簡単に理解する 1024KB の小さな

buffer
    オブジェクトを構築します。現在の
  1. slab は 1024KB で占有されます。レコードはどこからのものです この slab はどこから使用され始めますか?

Node.js の Buffer モジュールを簡単に理解するこの時点で、

を作成しますサイズが 3072KB のbuffer
    オブジェクト。構築プロセスでは、現在の
  1. slab の残りのスペースが十分であるかどうかが判断され、十分な場合は、残りのスペースを使用して、slab の割り当てステータスを更新します。 3072KB のスペースが使用された後、このスラブの残りのスペースは現在 4096KB です。

Node.js の Buffer モジュールを簡単に理解するこの時点で 6144KB のサイズの

buffer
    を作成すると、現在のスラブ領域では不十分であり、新しいスラブ領域が
  1. スラブが構築されます (これにより、元のスラブの残りのスペースが無駄になります)

たとえば、次のようになります。例: ###

Buffer.alloc(1)
Buffer.alloc(8192)
ログイン後にコピー

第一个slab中只会存在1字节的buffer对象,而后一个buffer对象会构建一个新的slab存放

由于一个slab可能分配给多个Buffer对象使用,只有这些小buffer对象在作用域释放并都可以回收时,slab的空间才会被回收。 尽管只创建1字节的buffer对象,但是如果不释放,实际是8KB的内存都没有释放

小结:

真正的内存是在Node的C++层面提供,JavaScript层面只是使用。当进行小而频繁的Buffer操作时,采用slab的机制进行预先申请和时候分配,使得JavaScript到操作系统之间不必有过多的内存申请方面的系统调用。 对于大块的buffer,直接使用C++层面提供的内存即可,无需细腻的分配操作。

Buffer的拼接

buffer在使用场景中,通常是以一段段的方式进行传输。

const fs = require(&#39;fs&#39;);

let rs = fs.createReadStream(&#39;./静夜思.txt&#39;, { flags:&#39;r&#39;});
let str = &#39;&#39;
rs.on(&#39;data&#39;, (chunk)=>{
    str += chunk;
})

rs.on(&#39;end&#39;, ()=>{
    console.log(str);
})
ログイン後にコピー

以上是读取流的范例,data时间中获取到的chunk对象就是buffer对象。

但是当输入流中有宽字节编码(一个字占多个字节)时,问题就会暴露。在str += chunk中隐藏了toString()操作。等价于str = str.toString() + chunk.toString()

下面将可读流的每次读取buffer长度限制为11.

fs.createReadStream(&#39;./静夜思.txt&#39;, { flags:&#39;r&#39;, highWaterMark: 11});
ログイン後にコピー

输出得到:

Node.js の Buffer モジュールを簡単に理解する

上面出现了乱码,上面限制了buffer长度为11,对于任意长度的buffer而言,宽字节字符串都有可能存在被截断的情况,只不过buffer越长出现概率越低。

encoding

但是如果设置了encodingutf-8,就不会出现此问题了。

fs.createReadStream(&#39;./静夜思.txt&#39;, { flags:&#39;r&#39;, highWaterMark: 11, encoding:&#39;utf-8&#39;});
ログイン後にコピー

Node.js の Buffer モジュールを簡単に理解する

原因: 虽然无论怎么设置编码,流的触发次数都是一样,但是在调用setEncoding时,可读流对象在内部设置了一个decoder对象。每次data事件都会通过decoder对象进行buffer到字符串的解码,然后传递给调用者。

string_decoder 模块提供了用于将 Buffer 对象解码为字符串(以保留编码的多字节 UTF-8 和 UTF-16 字符的方式)的 API

const { StringDecoder } = require(&#39;string_decoder&#39;);
let s1 = Buffer.from([0xe7, 0xaa, 0x97, 0xe5, 0x89, 0x8d, 0xe6, 0x98, 0x8e, 0xe6, 0x9c])
let s2 = Buffer.from([0x88, 0xe5, 0x85, 0x89, 0xef, 0xbc, 0x8c, 0x0d, 0x0a, 0xe7, 0x96])
console.log(s1.toString());
console.log(s2.toString());
console.log(&#39;------------------&#39;);

const decoder = new StringDecoder(&#39;utf8&#39;);
console.log(decoder.write(s1));
console.log(decoder.write(s2));
ログイン後にコピー

Node.js の Buffer モジュールを簡単に理解する

StringDecoder在得到编码之后,知道了宽字节字符串在utf-8编码下是以3个字节的方式存储的,所以第一次decoder.write只会输出前9个字节转码的字符,后两个字节会被保留在StringDecoder内部。

Buffer与性能

buffer在文件I/O和网络I/O中运用广泛,尤其在网络传输中,性能举足轻重。在应用中,通常会操作字符串,但是一旦在网络中传输,都需要转换成buffer,以进行二进制数据传输。 在web应用中,字符串转换到buffer是时时刻刻发生的,提高字符串到buffer的转换效率,可以很大程度地提高网络吞吐率。

如果通过纯字符串的方式向客户端发送,性能会比发送buffer对象更差,因为buffer对象无须在每次响应时进行转换。通过预先转换静态内容为buffer对象,可以有效地减少CPU重复使用,节省服务器资源。

可以选择将页面中动态和静态内容分离,静态内容部分预先转换为buffer的方式,使得性能得到提升。

在文件的读取时,highWaterMark设置对性能影响至关重要。在理想状态下,每次读取的长度就是用户指定的highWaterMark

highWaterMark大小对性能有两个影响的点:

  • 对buffer内存的分配和使用有一定影响
  • 设置过小,可能导致系统调用次数过多

更多node相关知识,请访问:nodejs 教程!!

以上がNode.js の Buffer モジュールを簡単に理解するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Nodeのメモリ制御に関する記事 Nodeのメモリ制御に関する記事 Apr 26, 2023 pm 05:37 PM

ノンブロッキングおよびイベント駆動に基づいて構築されたノード サービスには、メモリ消費量が少ないという利点があり、大量のネットワーク リクエストの処理に非常に適しています。大量のリクエストを前提として、「メモリ制御」に関する問題を考慮する必要があります。 1. V8 のガベージ コレクション メカニズムとメモリ制限 Js はガベージ コレクション マシンによって制御されます

Node V8 エンジンのメモリと GC の詳細な図による説明 Node V8 エンジンのメモリと GC の詳細な図による説明 Mar 29, 2023 pm 06:02 PM

この記事では、NodeJS V8 エンジンのメモリとガベージ コレクター (GC) について詳しく説明します。

最適な Node.js Docker イメージを選択する方法について話しましょう。 最適な Node.js Docker イメージを選択する方法について話しましょう。 Dec 13, 2022 pm 08:00 PM

ノード用の Docker イメージの選択は些細なことのように思えるかもしれませんが、イメージのサイズと潜在的な脆弱性は、CI/CD プロセスとセキュリティに大きな影響を与える可能性があります。では、最適な Node.js Docker イメージを選択するにはどうすればよいでしょうか?

Node の File モジュールについて詳しく説明しましょう Node の File モジュールについて詳しく説明しましょう Apr 24, 2023 pm 05:49 PM

ファイル モジュールは、ファイルの読み取り/書き込み/開く/閉じる/削除の追加など、基礎となるファイル操作をカプセル化したものです。ファイル モジュールの最大の特徴は、すべてのメソッドが **同期** と ** の 2 つのバージョンを提供することです。 asynchronous**、sync サフィックスが付いているメソッドはすべて同期メソッドであり、持たないメソッドはすべて異種メソッドです。

Node.js 19 が正式リリースされました。その 6 つの主要な機能についてお話しましょう。 Node.js 19 が正式リリースされました。その 6 つの主要な機能についてお話しましょう。 Nov 16, 2022 pm 08:34 PM

Node 19 が正式リリースされましたので、この記事では Node.js 19 の 6 つの主要な機能について詳しく説明します。

Node.js の GC (ガベージ コレクション) メカニズムについて話しましょう Node.js の GC (ガベージ コレクション) メカニズムについて話しましょう Nov 29, 2022 pm 08:44 PM

Node.js はどのように GC (ガベージ コレクション) を行うのでしょうか?次の記事で詳しく説明します。

Nodeのイベントループについて話しましょう Nodeのイベントループについて話しましょう Apr 11, 2023 pm 07:08 PM

イベント ループは Node.js の基本的な部分であり、メイン スレッドがブロックされていないことを確認することで非同期プログラミングが可能になります。イベント ループを理解することは、効率的なアプリケーションを構築するために重要です。次の記事では、Node のイベント ループについて詳しく説明します。お役に立てれば幸いです。

ノードがnpmコマンドを使用できない場合はどうすればよいですか? ノードがnpmコマンドを使用できない場合はどうすればよいですか? Feb 08, 2023 am 10:09 AM

ノードが npm コマンドを使用できない理由は、環境変数が正しく設定されていないためです。解決策は次のとおりです: 1. 「システムのプロパティ」を開きます; 2. 「環境変数」->「システム変数」を見つけて、環境を編集します。変数; 3.nodejs フォルダーの場所を見つけます; 4.「OK」をクリックします。

See all articles