概要概要
この本の説明は一般的で、主に説明のためです
缓冲区
通道
选择器
正则表达式
字符集
これは主に、APIの使用法と、比較的低レベルのいくつかのシステム知識を説明します。それらのほとんどは、コードのソースコードの説明、またはAPIの使用法の説明です。
あなたはnettyを学ぶ前にこれを見ることができます、あるいは2つはお互いを補うことができます。
Nettyを使用しない場合は、学習しないことをお勧めします。比較的低レベルであり、読んだ後は忘れてしまいます。
弾丸を噛んで大まかに読んで、時間があればもう一度見てみましょう。
1はじめに
javaioとsystemioの違い
ほとんどの場合、JavaアプリケーションはI / Oによって実際には制約されません。オペレーティングシステムが
データを迅速に転送できないため、Javaが何かをする必要があるわけではありません。逆に、JVM自体はI / Oの点で効率的ではありません。オペレーティングシステム
は、JavaのストリームベースのI / Oモデルと一致しません。オペレーティングシステムが移動したいのは、データの大きなブロック(バッファ)です。これは
、ハードウェアダイレクトメモリアクセス(DMA)の助けを借りて行われることがよくあります。JVMのI / Oクラスは、1バイト、数行のテキストなどの小さなデータを操作するのが好きです。その結果、
オペレーティングシステムはバッファ全体でデータを送信し、java.ioのストリームデータクラスはデータを小さな断片に分割するのに多くの時間を費やし、多くの場合
、オブジェクトの複数のレイヤーとの間で小さな断片をコピーします。オペレーティングシステムはトラック全体でデータを転送するのが好きで、java.ioクラスは1つのシャベルで
データを処理するのが好きです。NIOを使用すると、大量のデータを直接使用できる場所(ByteBuffer
オブジェクト)に簡単にバックアップできます。
配列ベースのread()メソッドとwrite()メソッドに固執するだけです。これらのメソッドは、基盤となるオペレーティングシステムコールに非常に近いものですが、バッファのコピーを少なくとも1つ保持する必要があります。
バッファ、およびバッファの動作方法は、すべてのI / Oの基礎です。いわゆる「入力/出力」は、データをバッファに出し入れすることに他なりません。
I / Oバッファの動作図
3つのバッファの発散読み取り操作
メモリ空間の複数のマッピング
前提条件は、カーネルバッファーとユーザーバッファーが同じページ配置を使用する必要があり、バッファーのサイズもディスクコントローラーのブロックサイズ(通常は512バイトのディスクセクター)の倍数である必要があります。オペレーティングシステムは、メモリアドレス空間を固定サイズのバイトグループであるページに分割します。メモリページのサイズは常にディスクブロックサイズの倍数であり、通常は2の累乗です(これにより、アドレス指定操作が簡素化されます)。
ページフォールトはすぐにトラップ(システムコールと同様)を生成します。トラップは、エラーの原因となった仮想アドレスに関する情報とともに制御をカーネルに転送し、カーネルはページの有効性を検証するための手順を実行します。
1.4.1ファイルIO
- ディスクはハードウェアデバイスであり、ファイルについては何も知りません。
- ファイルシステムは、より高いレベルの抽象化であり、ディスク(または他のランダムアクセスブロックデバイス)上のデータを配置および解釈する独自の方法です。
ユーザーメモリからファイルシステムページへのマッピング
ファイルロック
- ファイルロックメカニズムにより、プロセスは他のプロセスがファイルにアクセスするのを防いだり、そのアクセス方法を制限したりできます。通常の使用法は、共有情報の更新方法を制御すること、またはトランザクションを分離することです。ファイルロックは、複数のエンティティによる共通リソースへの同時アクセスを制御するために不可欠です。
数据库等复杂应用严重信赖于文件锁定
ファイルをロックするには、共有と排他の2つの方法があります。複数の共有ロックが同じファイル領域に同時に作用する可能性があります。排他ロックは異なり、関連する領域で他のロックを有効にすることはできません。
2.バッファ
- バッファは、オブジェクトにラップされた基本的なデータ要素の配列です。
2.1プロパティ
すべてのバッファには、含まれるデータ要素に関する情報を提供する4つの属性があります。彼らです:
容量
バッファが保持できるデータ要素の最大数。この容量は、バッファの作成時に設定され、変更することはできません。
上限(制限)
読み取りまたは書き込みができないバッファーの最初の要素。つまり、バッファ内の既存の要素の数です。
ポジション
読み取りまたは書き込みが行われる次の要素のインデックス。位置は、対応するget()関数とput()関数によって自動的に更新されます。
マーク
メモの場所。mark()を呼び出して、mark = postionを設定します。reset()を呼び出して、position = markを設定します。マークは設定前に未定義です。
4つの属性は、常に次の関係に従います。
0 <= mark <= position <= limit <= capacity
この章では、主にさまざまなバッファを紹介します。
2.2フリップ
Flip()関数は、満たされた状態のデータ要素を、要素を読み取る準備ができている解放された状態に追加し続けることができるバッファーを反転します。
以下のコードと同様
buffer.limit(buffer.position()).position(0);
2.3クリア
Clear()関数は、バッファーを空の状態にリセットします。バッファ内のデータ要素は変更されませんが、容量の値の上限が設定され、位置が0に戻されるだけです。
2.4マーク
バッファが位置を記憶し、後で返すことができるようにマークを付けます。バッファのマークは、mark()関数が呼び出される前は未定義であり、マークは呼び出されたときに現在の位置の値に設定されます。reset()関数は、位置を現在のマーク値に設定します。マーク値が定義されていない場合、reset()を呼び出すとInvalidMarkException例外が発生します。一部のバッファ関数は、設定されているフラグを破棄します(rewind()、clear()、flip()は常にマークを破棄します)。新しく設定された値が現在のマークよりも小さい場合、インデックスパラメータを指定してlimit()またはposition()を呼び出すと、マークが破棄されます。
2.5比較
2つのバッファーが等しいと見なされるための必要十分条件は次のとおりです。32
- 2つのオブジェクトは同じタイプです。異なるデータ型を含むバッファーが等しくなることはなく、バッファーが非バッファーオブジェクトと等しくなることもありません。
- 両方のオブジェクトには、同じ数の要素が残っています。バッファの容量は同じである必要はなく、バッファ内の残りのデータのインデックスも同じである必要はありません。ただし、各バッファの残りの要素の数(位置から上限まで)は同じである必要があります。
- 各バッファのGet()関数によって返される必要がある残りのデータ要素のシーケンスは一貫している必要があります。
等しいと見なされる2つのバッファー
等しくないと見なされる2つのバッファー
3.6バイトオーダー
ビッグエンディアンのバイトオーダー
リトルエンディアンのバイト順序
マルチバイト値がメモリに格納される方法は、一般にエンディアンネス(バイトオーダー)と呼ばれます。デジタル値の最上位バイトであるビッグエンド(ビッグエンド)が下位アドレスにある場合、システムはビッグエンディアンのバイト順です。最下位バイトが最初にメモリに格納される場合、次にリトルエンディアンのバイト順序。
ByteOrderクラスは、バッファーからマルチバイト値を格納または取得するときに使用するバイト順序を決定する定数を定義します。
ByteBufferクラスは異なります。システムの固有のバイト順序に関係なく、デフォルトのバイト順序は常にByteBuffer.BIG_ENDIANです。Javaのデフォルトのバイト順序は、ビッグエンディアンのバイト順序です。