ノードの内部メカニズムについて
残念ながら、Node.jsの多くのマニュアルと本は、このプラットフォームの内部メカニズムに十分な注意を払っておらず、それらの存在の目的を説明しようともしていません。 原則として、このような出版物では、実装の詳細に立ち入ることなく、既製のパッケージを使用したWebアプリケーションの開発に関するすべての話になります。 また、いくつかの場所では、読者がこれをすべて理解する必要はないと恥知らずに述べられています。なぜなら、おそらくBufferクラスのオブジェクトを直接操作する必要がないからです。
プロジェクトで既製のライブラリを使用する以上のことを計画していない人にとって、このアプローチはおそらく正当化されます。 謎が好奇心を呼び覚ます同じように、JSの独自の理解を新たなレベルに引き上げたい人は、たとえば
Buffer
クラスなど、Node.jsの内部機能の多くをより深く掘り下げて対処する必要があります。
Buffer
クラスに関するNode.jsの公式ドキュメントでは、次を読むことができます。
ECMAScript 2015(ES6)でTypedArrayが登場する前は、JavaScriptにはバイナリデータストリームを読み取ったり、他の操作を実行したりするメカニズムがありませんでした。 BufferクラスはNode.js APIの一部として導入されました。これにより、TCPストリームやファイルシステム操作などのコンテキストで任意のバイナリデータストリームとやり取りできます。
はい、以前にこの定義に現れる単語を知らなかった場合、あなたはそれをプログラムの専門用語の理解できない束として知覚するかもしれません。 この定義を言い換えることで、これらすべてを少し簡素化して、何も邪魔せずに作業できるようにしましょう。 この定義から、次のことが推測できます。
BufferクラスはNode.js APIの一部として導入され、バイナリデータストリームの操作を可能にします。
そのため、すべてが少し簡単になりました。 しかし、「バッファクラス」、「ストリーム」、「バイナリデータ」-まだ複雑な概念が多すぎます。 後者から始めて、それらに対処しようとします。
バイナリデータとは何ですか?
コンピュータがデータをバイナリ形式で保存および表示することを既にご存知かもしれません。 バイナリデータは、1と0の単なるコレクションです。 たとえば、値「1」と「0」で構成される5つの異なるバイナリデータセットを次に示します。
10, 01, 001, 1110, 00101011
セット内の各値「1」と「0」の各バイナリ値は、ビット(ビット、バイナリdigIT、バイナリ桁)と呼ばれます。
特定のデータを処理するには、コンピューターはこのデータをバイナリ表現に変換する必要があります。 たとえば、10進数の12を格納するには、コンピューターはそれをバイナリ形式、つまり1100に変換する必要があります。
コンピューターは、そのような変換を行う方法をどのように知っていますか? これは純粋な数学です。 これは、学校で研究されている2進数のシステムです。 10進数を2進数に変換する規則があり、コンピューターはこれらの規則を理解しています。
ただし、使用するデータ型は数字だけではありません。 線、画像、さらにはビデオもあります。 コンピューターは、データ型をバイナリ形式で表現する方法を知っています。 文字列を例にとります。 コンピュータは文字列「L」をバイナリでどのように表示しますか? 文字列をバイナリ形式で保存するには、コンピューターはまずこの文字列の文字を数字に変換してから、これらの数字をバイナリ表現に変換する必要があります。 したがって、1文字の文字列の場合、コンピューターはまず「L」をこの文字が表す数字に変換する必要があります。 JavaScriptでこれがどのように行われるかを見てみましょう。
ブラウザー開発者ツールコンソールを開き、次のコードをそこに貼り付けます。
"L".charCodeAt(0)
Enter
押します。 何を見ましたか? 数76? これは、いわゆる数値表現、またはコード、または文字Lのコードポイントです。しかし、コンピューターはどの番号が特定の文字に対応するかをどのように知るのでしょうか。 彼は、76という数字がLという文字に対応していることをどのようにして知るのでしょうか?
文字セット
文字セットは、文字と数値コードとの対応に関する事前定義されたルールです。 そのようなルールには多くの種類があります。 たとえば、非常に人気のあるものはUnicodeとASCIIです。 JavaScriptは、Unicode文字セットの操作に非常に優れています。 実際、L文字を数字76に変換するためにブラウザーで使用されるのはUnicode文字テーブルであり、それに対応するルールが書き込まれます。
それで、コンピューターが数字の形で記号をどのように表すかを見ました。 ここで、76という数字がどのようにバイナリ表現に変わるかについて説明しましょう。 このためには、76を10進数から2進数に変換するだけで十分のように思えるかもしれませんが、すべてがそれほど単純ではありません。
文字エンコード
文字の数値コードへの対応を示す規則があるように、数値をバイナリ表現に変換する規則があります。 特に、数値を表すために使用する必要があるビット数に関連しています。 これは文字エンコードと呼ばれます。
文字エンコード規則セットの1つはUTF-8と呼ばれます。 UTF-8は、文字をバイトに変換する規則を定義します。 1バイトは8ビットのセットであり、8ユニットとゼロです。 したがって、任意の文字のコードポイントを表すには、8つの1と0のセットを使用する必要があります。 このステートメントを扱います。
既に述べたように、10進数12のバイナリ表現は1100です。したがって、UTF-8が12を8ビット値で表すことを示している場合、これはコンピュータが12の実際のバイナリ表現の左に数ビットを追加する必要があることを意味しますシングルバイトとして表すため。 その結果、12を00001100として保存する必要があります。数字76は01001100のようになります。
これは、コンピューターが文字列または単一の文字をバイナリ形式で保存する方法です。 これと同様に、マシンには画像とビデオをバイナリ形式に変換するための特別なルールがあります。 このすべてのポイントは、コンピューターがすべてのデータ型をバイナリ形式で保存することであり、これはすべてバイナリデータと呼ばれます。
文字エンコードの複雑さに興味がある場合は、 この資料をご覧ください。 この資料では、これらすべてについて詳しく説明しています。
これで、バイナリデータとは何かを理解できましたが、上記のバイナリデータストリームとは何ですか?
流れ
Node.jsのストリームは、ある場所から別の場所に移動される一連のデータです。 データの移動はすぐには行われず、時間がかかります。 ここでの主なアイデアは、スレッドを使用すると、大きなデータセットを部分的に処理できることです。
バッファの定義から、つまり「ファイルシステムのコンテキストでのバイナリデータストリーム」を参照していることを思い出すと、たとえば、後で作業するためにこれらのファイルを読み取るときなど、ファイルからバイナリデータを移動することについて話していることがわかりますその内容。
file1.txt
からテキストを読み取り、変換して
file1.txt
に保存するとし
file2.txt
。
そして、バッファはどこにありますか? ストリーム形式のバイナリデータの操作にどのように役立ちますか?
緩衝液
「データストリーム」とは、ある場所から別の場所へのデータの移動であることを思い出してください。 次に、このデータがどのように正確に移動するかを自問します。
通常、データは少なくとも読み取られ、後続の処理で使用できるように移動されます。 データに基づいて何らかの決定を下すために言う。 コンピューターの処理速度は制限されているため、プロセスが一定期間に処理できるデータの最小量と最大量を表す特定のフレームワークについて話すことができます。 そのため、データを受信する速度が消費される速度よりも速い場合、冗長データはその順番が処理されるまで待機する必要があります。
一方、システムが到着するよりも速くデータを処理できる場合、特定のデータパケットを処理する次のセッションよりも早く到着する一定量のデータに対して、すべてのデータが処理のために送信される前に、さらにデータが到着するのを待つ必要があります。
この「待機エリア」がバッファです! バッファの物理的表現は、RAM内のスペースである場合があります。このスペースでは、データはストリームを処理している間に一時的に蓄積され、インラインで待機し、最終的に処理のために送信されます。
これはすべて、バス停の形で想像できます。 一部の駅では、一定数の乗客がいるまで、または出発時刻までバスを送信できません。 さらに、乗客はさまざまな速度で駅に到着できます。 同時に、駅に到着する乗客のプロセスを明確に制御する人はいません。
いずれにしても、バスの出発前に到着した乗客は、駅の管理者がバスの出発時刻であると判断するまで待つ必要があります。 また、バスがすでに満車の場合、またはバスがすでに出発したときに到着した乗客は、次のバスを待つ必要があります。
いずれにせよ、私たちは一種の「待合室」について話している。 Node.jsのバッファは同じ役割を果たします。 Node.jsは、データが到着する速度やデータが到着する時間を制御できません。 彼は、処理のためにすでに到着したデータの送信についてのみ決定できます。 処理のためにデータを送信する時間がまだ到着していない場合、Node.jsはそれをバッファー(「待機領域」)に入れます。
動作中のバッファに遭遇する典型的な例は、インターネットでビデオを見ていることです。 インターネット接続が十分に速い場合、フローレートはビデオプレーヤーのバッファをすぐにいっぱいにしてプレーヤーにビデオを表示させ、次に次のバッファをいっぱいにして視聴のために送信するなど、ビデオ転送が完了するまで続きます。 以下は、データが処理されるよりも早く到着するシステムの例です。
ただし、接続が特定の速度で変わらない場合、最初に到着したデータのセットを処理した後、プレーヤーはデータ読み込みアイコンを表示するか、「バッファリング」という単語を表示します。つまり、ビデオが表示される前にさらにデータが到着することを期待します。 バッファがいっぱいになり、受信したデータが処理されると、プレーヤーはビデオを表示します。 ビデオを再生する過程で、新しいデータが到着し、バッファで順番が変わるのを待ちます。 これは、システムがデータを入力するよりも速く処理できる場合にのみ当てはまります。
プレーヤーが以前に受信したデータの再生を終了し、バッファがまだいっぱいになっていない場合、「バッファリング」という碑文が再び表示され、システムは入力する必要があるデータ量を待ちます。 実際、Nodeでは、バッファーの操作は次のようになります。
バッファの元の定義から、データがバッファにある場合、それらを操作できることがわかります。 生のバイナリデータで何ができますか?
バッファーを操作する
Node.jsでのバッファーの実装は、データを操作するための多くのオプションを提供します。 さらに、自分でバッファを作成し、その特性を設定できます。 そのため、Node.jsがデータ転送中に自動的に作成するバッファーに加えて、独自のバッファーを作成して操作できます。 バッファを作成するにはさまざまな方法があります。 それらのいくつかを見てみましょう。
// 10. // 10 . const buf1 = Buffer.alloc(10); // . const buf2 = Buffer.from("hello buffer");
バッファを作成したら、作業を開始できます。
// buf1.toJSON() // { type: 'Buffer', data: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] } // buf2.toJSON() // { type: 'Buffer', data: [ 104, 101, 108, 108, 111, 32, 98, 117, 102, 102, 101, 114 ] } // toJSON() Unicode // buf1.length // 10 buf2.length // 12. , , . // buf1.write("Buffer really rocks!") // buf1.toString() // 'Buffer rea' // , buf1 10, 10
まとめ
「バッファ」、「ストリーム」、および「バイナリデータ」が何であるかを理解したので、バッファに関するドキュメントを開き、そこで説明されているすべてを有意義に実験できます。
さらに、実際のバッファの動作を確認するには、zlib.jsライブラリのソースコードを読んでください。 これは、Node.jsのコアライブラリの1つです。 バイナリデータストリームと対話するために、このライブラリでバッファがどのように使用されるかを見てください。 ここでは、gzipアーカイブを表すファイルを使用して作業が行われます。
この資料から学んだこと、ドキュメントで見つけたこと、コードを分析して学んだことが、あなたの専門的レベルを上げ、プロジェクトで役立つことを願っています。
親愛なる読者! Node.jsの初心者デベロッパーが注意を払うべき基本的なことは何ですか?