目次
バイナリの基礎
この関数は、バッファを作成するために 最も一般的に使用される
渡す最初のパラメータが String## の場合# type の場合、Buffer.from は、文字列のエンコーディング (
Buffer.from(arrayBuffer[, byteOffset[, length]])
buf.length
Buffer.poolSize
buf.write(string[, offset,[, length]][, encoding])
Buffer.concat(list[, totalLength])
概要
ホームページ ウェブフロントエンド jsチュートリアル この記事では、Node の Buffer クラスについて詳しく説明します。

この記事では、Node の Buffer クラスについて詳しく説明します。

Dec 12, 2022 pm 07:36 PM
javascript フロントエンド node.js

この記事では、Node の Buffer クラスについて詳しく説明します。皆様のお役に立てれば幸いです。

この記事では、Node の Buffer クラスについて詳しく説明します。

TypedArray が登場する前は、JavaScript 言語は raw binary data(raw binary data) をうまく扱うことができませんでした。 JavaScript は当初、主にブラウザーのスクリプト言語として使用されていたため、ネイティブ バイナリ データを処理する必要があるシナリオはほとんどなかったためです。 Node が登場した後、サーバー側アプリケーションは ファイルの読み書き TCP 接続 などの多数のバイナリ ストリームを処理する必要があるためです。 , ノードは JavaScript (V8) 内にあります。また、新しいデータ型 Buffer が定義されています。 Buffer は Node アプリケーションで広く使用されているため、その使用法を真にマスターすることによってのみ、より優れた Node アプリケーションを作成できます。 [関連するチュートリアルの推奨事項: nodejs ビデオ チュートリアル プログラミング指導 ]

バイナリの基礎


正式なはじめに Buffer の具体的な使い方の前に、バイナリに関する知識を簡単に復習しましょう。

プログラマとして、私たちは皆バイナリについてよく知っている必要があります。コンピュータの基礎となるデータはすべてバイナリ (バイナリ) 形式で保存されているためです。つまり、コンピュータ内のファイルは、プレーン テキスト、画像、ビデオのいずれであっても、コンピュータのハード ドライブ上の 2 つの番号 01 で構成されています。コンピューター サイエンスでは、単一の数値 0 または 1 ビット (ビット) と呼び、8 ビット で ## を形成できます。 #バイト(バイト)。 10 進数 16 が 1 バイトで表される場合、基礎となるストレージ構造は次のとおりです: 16 が 2 進数で表される場合、10 進数よりも 6 桁多いことがわかります。は 2 進数になるため、読み取りと書き込み 截屏2022-10-15 下午2.23.13.png には非常に不便になります。このため、プログラマーは通常、バイナリを直接使用する代わりに、hexadecimal (16 進数) を使用してデータを表すことを好みます。たとえば、CSS を記述するときは、color の値を使用します。16 進数 (例: #FFFFFF) 0 と 1 の束の代わりに。

文字エンコーディングすべてのデータの最下層はバイナリであり、ネットワーク上で送信されるデータもバイナリであるため、この記事はなぜ私たちは今読んでいます

#0

1 の束の代わりに ##中文 はどうでしょうか?ここでは、文字エンコーディングの概念を紹介します。いわゆる 文字エンコードは、単なる マッピング関係テーブル であり、文字 (漢字、英語文字、またはその他の文字) と 2 進数 (数バイトを含む)相互に対応します。たとえば、使い慣れた ascii を使用してエンコードすると、英語文字 a のバイナリ表現は 0b01100001 になります (0b はバイナリです)番号プレフィックス)。したがって、コンピューターが ascii エンコードされた ファイルからバイナリ データ 0b01100001 の文字列を読み取ると、文字 a が画面に表示されます。 a は、コンピューターに保存またはネットワーク上で送信される場合の 0b01100001 のバイナリ データです。 ascii コードに加えて、一般的な文字エンコーディングには utf-8utf-16 などが含まれます。 バッファ

基本的な

バイナリ知識

文字エンコーディングの概念を習得したら、いよいよ正式に学習できるようになります。 ###バッファ###。 Buffer:Node.js の Buffer
クラスは、生のバイナリ データを処理するように設計されています。各バッファは、V8 の外部に割り当てられた生のメモリに対応します。バッファは整数の配列のように動作しますが、サイズ変更はできず、バイナリ データに特化したメソッドが多数あります。バッファ内の整数はそれぞれ 1 バイトを表すため、次の値に制限されます。値は 0 ~ 255 です。

console.log()
を使用して

Buffer インスタンスを出力すると、一連の値が 16 進数値で取得されます。

簡単に言えば、いわゆる バッファ は、V8 ヒープ メモリ の外側にノードによって割り当てられる 固定サイズ メモリ空間です。 console.log を使用して Buffer を出力すると、16 進数 ## の文字列が bytes 単位で出力されます。 # は値を表します。

バッファの作成

Buffer の基本概念を理解した後、Buffer を作成しましょう物体。 Buffer を作成する方法は数多くありますが、一般的な方法は Buffer.allocBuffer.allocUnsafe、および Buffer.from です。

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

これはバッファを作成する最も一般的な方法です。バッファのサイズを渡すだけで済みます

const buff = Buffer.alloc(5)

console.log(buff)
// Prints: <Buffer 00 00 00 00 00>
ログイン後にコピー

上記のコードでは、##5 バイト

のサイズのバッファー領域を作成しました。console.log 関数は、内容を示す 5 つの連続する 16 進数を出力します。現在バッファに保存されています。現在のバッファが 0 で満たされていることがわかります。これはノードのデフォルトの動作です。次の 2 つのパラメータ fillencoding を設定して、Fill を指定できます。初期化中の追加コンテンツ内。 ここで言及しておく価値があるのは、上記のコードでは、

node:buffer

パッケージから明示的にインポートせずに、Node グローバル Buffer オブジェクトを使用しているということです。実際の開発では、 後者の を使用する必要があります:

import { Buffer } from &#39;node:buffer&#39;
ログイン後にコピー

Buffer.allocUnsafe(size)

Buffer.allocUnsafe

Buffer.alloc の違いは、allocUnsafe 関数の使用に適用されるメモリ空間が 初期化されていないことです。つまり、前回使用したデータがまだ残っている可能性があるため、データ セキュリティの問題が発生します。 allocUnsafe この関数は、バッファ領域のサイズとして size パラメータを受け取ります。

const buff = Buffer.allocUnsafe(5)

console.log(buff)
// Prints (实际内容可能有出入): <Buffer 8b 3f 01 00 00>
ログイン後にコピー
上記の出力結果から判断すると、 の使用を制御できません。 Buffer.allocUnsafe

割り当てられたバッファの内容。割り当てられたメモリが初期化されていないため、この関数は

Buffer.alloc よりも高速にバッファを割り当てます。実際の開発では、実際のニーズに基づいて選択する必要があります。 Buffer.from

この関数は、バッファを作成するために 最も一般的に使用される

関数であり、さまざまな

オーバーロードがありますつまり、渡されるパラメーターが異なれば、動作も異なります。いくつかの一般的なオーバーロードを見てみましょう: Buffer.from(string[, encoding])

渡す最初のパラメータが String## の場合# type の場合、Buffer.from は、文字列のエンコーディング (

encoding

パラメーター、デフォルトは utf8) に基づいて、文字列に対応するバイナリ表現を生成します。例を見てみましょう:

const buff = Buffer.from(&#39;你好世界&#39;)

console.log(buff)
// Prints: <Buffer e4 bd a0 e5 a5 bd e4 b8 96 e7 95 8c>
console.log(buff.toString())
// Prints: &#39;你好世界&#39;
console.log(buff.toString(&#39;ascii&#39;))
// Prints: &#39;&#39;d= e%=d8\x16g\x15\f&#39;&#39;
ログイン後にコピー
上記の例では、文字列 "Hello World" を使用してバッファの初期化を完了しました。2 番目の encoding パラメータを渡さなかったため、デフォルトのエンコードは

utf8

です。その後、最初の console.log の出力を見ると、渡した文字列には 4 文字しかありませんが、初期化されたバッファには 12 バイトがあることがわかります。 utf8 エンコーディングの中国語文字は表現するために 3 バイトを使用するためです。次に、buff.toString() メソッドを使用してバフの内容を表示します。toString メソッドのデフォルトのエンコード出力形式は utf8 であるため、2 番目の ## が表示されます。 #console .log は、buff ストレージの内容を正しく出力できます。ただし、3 番目の console.log では、文字エンコーディング タイプが ascii であると指定されており、この時点で大量の文字化けが確認されます。これを見ると、先ほど述べた 文字エンコーディング についての理解がさらに深まったと思います。 Buffer.from(buffer)

Buffer.from で受け取ったパラメータがバッファ オブジェクトの場合、Node は新しい Buffer インスタンスを作成し、それをバッファの内容を新しい Buffer オブジェクトに

copy します。
const buf1 = Buffer.from(&#39;buffer&#39;)
const buf2 = Buffer.from(buf1)

console.log(buf1)
// Prints: <Buffer 62 75 66 66 65 72>
console.log(buf2)
// Prints: <Buffer 62 75 66 66 65 72>

buf1[0] = 0x61

console.log(buf1.toString())
// Prints: auffer
console.log(buf2.toString())
// Prints: buffer
ログイン後にコピー

上記の例では、最初にバッファ オブジェクト

buf1 を作成しました。そこに格納されるコンテンツは文字列「buffer」であり、次にこのバッファ オブジェクトを通じて新しいバッファ オブジェクトを初期化しました。 buf2

。このとき、

buf1 の最初のバイトを 0x61 (a のエンコーディング) に変更すると、buf1 の出力が auffer になることがわかりました。 buf2 の内容は変更されていません。これは、Buffer.from(buffer) がデータのコピーであるという見解を裏付けています。

?注意:当Buffer的数据很大的时候,Buffer.from拷贝数据的性能是很差的,会造成CPU占用飙升,主线程卡死的情况,所以在使用这个函数的时候一定要清楚地知道Buffer.from(buffer)背后都做了什么。笔者就在实际项目开发中踩过这个坑,导致线上服务响应缓慢!

Buffer.from(arrayBuffer[, byteOffset[, length]])

说完了buffer参数,我们再来说一下arrayBuffer参数,它的表现和buffer是有很大的区别的。ArrayBuffer是ECMAScript定义的一种数据类型,它简单来说就是一片你不可以直接(或者不方便)使用的内存,你必须通过一些诸如Uint16ArrayTypedArray对象作为View来使用这片内存,例如一个Uint16Array对象的.buffer属性就是一个ArrayBuffer对象。当Buffer.from函数接收一个ArrayBuffer作为参数时,Node会创建一个新的Buffer对象,不过这个Buffer对象指向的内容还是原来ArrayBuffer的内容,没有任何的数据拷贝行为。我们来看个例子:

const arr = new Uint16Array(2)

arr[0] = 5000
arr[1] = 4000

const buf = Buffer.from(arr.buffer)

console.log(buf)
// Prints: <Buffer 88 13 a0 0f>

// 改变原来数组的数字
arr[1] = 6000

console.log(buf)
// Prints: <Buffer 88 13 70 17>
ログイン後にコピー

从上面例子的输出我们可以知道,arrbuf对象会共用同一片内存空间,所以当我们改变原数组的数据时,buf的数据也会发生相应的变化。

其它Buffer操作

看完了创建Buffer的几种做法,我们接着来看一下Buffer其它的一些常用API或者属性

buf.length

这个函数会返回当前buffer占用了多少字节

// 创建一个大小为1234字节的Buffer对象
const buf1 = Buffer.alloc(1234)
console.log(buf1.length)
// Prints: 1234

const buf2 = Buffer.from(&#39;Hello&#39;)
console.log(buf2.length)
// Prints: 5
ログイン後にコピー

Buffer.poolSize

这个字段表示Node会为我们预创建的Buffer池子有多大,它的默认值是8192,也就是8KB。Node在启动的时候,它会为我们预创建一个8KB大小的内存池,当用户用某些API(例如Buffer.alloc)创建Buffer实例的时候可能会用到这个预创建的内存池以提高效率,下面是一个具体的例子:

const buf1 = Buffer.from(&#39;Hello&#39;)
console.log(buf1.length)
// Prints: 5

// buf1的buffer属性会指向其底层的ArrayBuffer对象对应的内存
console.log(buf1.buffer.byteLength)
// Prints: 8192

const buf2 = Buffer.from(&#39;World&#39;)
console.log(buf2.length)
// Prints: 5

// buf2的buffer属性会指向其底层的ArrayBuffer对象对应的内存
console.log(buf2.buffer.byteLength)
// Prints: 8192
ログイン後にコピー

在上面的例子中,buf1buf2对象由于长度都比较小所以会直接使用预创建的8KB内存池。其在内存的大概表示如图:截屏2022-12-11 下午1.51.54.png这里值得一提的是只有当需要分配的内存区域小于4KB(8KB的一半)并且现有的Buffer池子还够用的时候,新建的Buffer才会直接使用当前的池子,否则Node会新建一个新的8KB的池子或者直接在内存里面分配一个区域(FastBuffer)。

buf.write(string[, offset,[, length]][, encoding])

这个函数可以按照一定的偏移量(offset)往一个Buffer实例里面写入一定长度(length)的数据。我们来看一下具体的例子:

const buf = Buffer.from(&#39;Hello&#39;)

console.log(buf.toString())
// Prints: "Hello"

// 从第3个位置开始写入&#39;LLO&#39;字符
buf.write(&#39;LLO&#39;, 2)
console.log("HeLLO")
// Prints: "HeLLO"
ログイン後にコピー

这里需要注意的是当我们需要写入的字符串的长度超过buffer所能容纳的最长字符长度(buf.length)时,超过长度的字符会被丢弃:

const buf = Buffer.from(&#39;Hello&#39;)

buf.write(&#39;LLO!&#39;, 2)
console.log(buf.toString())
// Print:s "HeLLO"
ログイン後にコピー

另外,当我们写入的字符长度超过buffer的最长长度,并且最后一个可以写入的字符不能全部填满时,最后一个字符整个不写入:

const buf = Buffer.from(&#39;Hello&#39;)

buf.write(&#39;LL你&#39;, 2)
console.log(buf.toString())
// Prints "HeLLo"
ログイン後にコピー

在上面的例子中,由于"你"是中文字符,需要占用三个字节,所以不能全部塞进buf里面,因此整个字符的三个字节都被丢弃了,buf对象的最后一个字节还是保持"o"不变。

Buffer.concat(list[, totalLength])

这个函数可以用来拼接多个Buffer对象生成一个新的buffer。函数的第一个参数是待拼接的Buffer数组,第二个参数表示拼接完的buffer的长度是多少(totalLength)。下面是一个简单的例子:

const buf1 = Buffer.from(&#39;Hello&#39;)
const buf2 = Buffer.from(&#39;World&#39;)

const buf = Buffer.concat([buf1, buf2])
console.log(buf.toString())
// Prints "HelloWorld"
ログイン後にコピー

上面的例子中,因为我们没有指定最终生成Buffer对象的长度,所以Node会计算出一个默认值,那就是buf.totalLength = buf1.length + buf2.length。而如果我们指定了totalLength的值的话,当这个值比buf1.lengh + buf2.length小时,Node会截断最后生成的buffer;如果指定的值比buf1.length + buf2.length大时,生成buf对象的长度还是totalLength,多出来的位数填充的内容是0。

这里还有一点值得指出的是,Buffer.concat最后拼接出来的Buffer对象是通过拷贝原来Buffer对象得出来,所以改变原来的Buffer对象的内容不会影响到生成的Buffer对象,不过这里我们还是需要考虑拷贝的性能问题就是了。

Buffer オブジェクトのガベージ コレクション

記事の冒頭で、Node 内のすべての Buffer オブジェクトによって割り当てられるメモリ領域は V8 から独立していると述べました。 ヒープ領域は、オフヒープメモリに属します。これは、Buffer オブジェクトが V8 ガベージ コレクション メカニズム の影響を受けず、手動でメモリを管理する必要があるということですか?実際にはいいえ、Node の API を使用して新しい Buffer オブジェクトを作成するたびに、各 Buffer オブジェクトは JavaScript 空間のオブジェクト (バッファ メモリへの参照) に対応します。このオブジェクトは V8 ガベージ コレクションによって制御されます。そして、Node が必要とするのは以下だけです。この reference がガベージ コレクションされるときに、いくつかのフックをハングして、バッファーが指すオフヒープ メモリを解放します。 簡単に言うと、Buffer によって割り当てられたスペースについて心配する必要はありません。V8 のガベージ コレクション メカニズムは、無駄なメモリを再利用するのに役立ちます。

概要

この記事では、Buffer の一般的な API やプロパティなど、Buffer の基本的な知識を紹介しました。この知識があなたの仕事に役立つことを願っています。 。 ヘルプ。

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

以上がこの記事では、Node の 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衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

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

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

PHP と Vue: フロントエンド開発ツールの完璧な組み合わせ PHP と Vue: フロントエンド開発ツールの完璧な組み合わせ Mar 16, 2024 pm 12:09 PM

PHP と Vue: フロントエンド開発ツールの完璧な組み合わせ 今日のインターネットの急速な発展の時代において、フロントエンド開発はますます重要になっています。 Web サイトやアプリケーションのエクスペリエンスに対するユーザーの要求がますます高まっているため、フロントエンド開発者は、より効率的で柔軟なツールを使用して、応答性の高いインタラクティブなインターフェイスを作成する必要があります。フロントエンド開発の分野における 2 つの重要なテクノロジーである PHP と Vue.js は、組み合わせることで完璧なツールと見なされます。この記事では、PHP と Vue の組み合わせと、読者がこれら 2 つをよりよく理解し、適用できるようにするための詳細なコード例について説明します。

Django はフロントエンドですか、バックエンドですか?それをチェックしてください! Django はフロントエンドですか、バックエンドですか?それをチェックしてください! Jan 19, 2024 am 08:37 AM

Django は、迅速な開発とクリーンなメソッドを重視した Python で書かれた Web アプリケーション フレームワークです。 Django は Web フレームワークですが、Django がフロントエンドなのかバックエンドなのかという質問に答えるには、フロントエンドとバックエンドの概念を深く理解する必要があります。フロントエンドはユーザーが直接対話するインターフェイスを指し、バックエンドはサーバー側プログラムを指し、HTTP プロトコルを通じてデータと対話します。フロントエンドとバックエンドが分離されている場合、フロントエンドとバックエンドのプログラムをそれぞれ独立して開発して、ビジネス ロジックとインタラクティブ効果、およびデータ交換を実装できます。

簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 Jan 05, 2024 pm 06:08 PM

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

Go 言語のフロントエンド テクノロジーの探求: フロントエンド開発の新しいビジョン Go 言語のフロントエンド テクノロジーの探求: フロントエンド開発の新しいビジョン Mar 28, 2024 pm 01:06 PM

Go 言語は、高速で効率的なプログラミング言語として、バックエンド開発の分野で広く普及しています。ただし、Go 言語をフロントエンド開発と結びつける人はほとんどいません。実際、フロントエンド開発に Go 言語を使用すると、効率が向上するだけでなく、開発者に新たな視野をもたらすことができます。この記事では、フロントエンド開発に Go 言語を使用する可能性を探り、読者がこの分野をよりよく理解できるように具体的なコード例を示します。従来のフロントエンド開発では、ユーザー インターフェイスの構築に JavaScript、HTML、CSS がよく使用されます。

フロントエンドの面接官からよく聞かれる質問 フロントエンドの面接官からよく聞かれる質問 Mar 19, 2024 pm 02:24 PM

フロントエンド開発のインタビューでは、HTML/CSS の基本、JavaScript の基本、フレームワークとライブラリ、プロジェクトの経験、アルゴリズムとデータ構造、パフォーマンスの最適化、クロスドメイン リクエスト、フロントエンド エンジニアリング、デザインパターン、新しいテクノロジーとトレンド。面接官の質問は、候補者の技術スキル、プロジェクトの経験、業界のトレンドの理解を評価するように設計されています。したがって、候補者はこれらの分野で自分の能力と専門知識を証明するために十分な準備をしておく必要があります。

Django: フロントエンド開発とバックエンド開発の両方を処理できる魔法のフレームワークです。 Django: フロントエンド開発とバックエンド開発の両方を処理できる魔法のフレームワークです。 Jan 19, 2024 am 08:52 AM

Django: フロントエンド開発とバックエンド開発の両方を処理できる魔法のフレームワークです。 Django は、効率的でスケーラブルな Web アプリケーション フレームワークです。 MVCやMTVなど複数のWeb開発モデルをサポートし、高品質なWebアプリケーションを簡単に開発できます。 Django はバックエンド開発をサポートするだけでなく、フロントエンド インターフェイスを迅速に構築し、テンプレート言語を通じて柔軟なビュー表示を実現します。 Django はフロントエンド開発とバックエンド開発をシームレスに統合するため、開発者は学習に特化する必要がありません。

JavaScript で HTTP ステータス コードを簡単に取得する方法 JavaScript で HTTP ステータス コードを簡単に取得する方法 Jan 05, 2024 pm 01:37 PM

JavaScript で HTTP ステータス コードを取得する方法の紹介: フロントエンド開発では、バックエンド インターフェイスとの対話を処理する必要があることが多く、HTTP ステータス コードはその非常に重要な部分です。 HTTP ステータス コードを理解して取得すると、インターフェイスから返されたデータをより適切に処理できるようになります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法と、具体的なコード例を紹介します。 1. HTTP ステータス コードとは何ですか? HTTP ステータス コードとは、ブラウザがサーバーへのリクエストを開始したときに、サービスが

Golang とフロントエンド テクノロジーの組み合わせ: Golang がフロントエンド分野でどのような役割を果たすかを探る Golang とフロントエンド テクノロジーの組み合わせ: Golang がフロントエンド分野でどのような役割を果たすかを探る Mar 19, 2024 pm 06:15 PM

Golang とフロントエンド テクノロジーの組み合わせ: Golang がフロントエンド分野でどのような役割を果たしているかを調べるには、具体的なコード例が必要です。インターネットとモバイル アプリケーションの急速な発展に伴い、フロントエンド テクノロジーの重要性がますます高まっています。この分野では、強力なバックエンド プログラミング言語としての Golang も重要な役割を果たします。この記事では、Golang がどのようにフロントエンド テクノロジーと組み合わされるかを検討し、具体的なコード例を通じてフロントエンド分野での可能性を実証します。フロントエンド分野における Golang の役割は、効率的で簡潔かつ学びやすいものとしてです。

See all articles