1。基本概念
IOは、メインメモリと外部デバイス(ハードディスク、端子、ネットワークなど)によるデータをコピーするプロセスです。 IOは、オペレーティングシステムの根本的な機能実装であり、I/O命令を通じて完了します。
すべての言語ランタイムシステムは、I/Oを実行するための高レベルのツールを提供します。 (c's printfscanf、Javaのオブジェクト指向のカプセル化)
2。Java Standard IOのレビュー
Java標準のIOクラスライブラリは、IOオブジェクト指向の抽象化です。ローカル方法の基礎となる実装に基づいて、基礎となる実装に注意を払う必要はありません。 inputstream/outputStream:一度に1つのバイトを転送します。リーダー/ライター:一度に1人のキャラクター。
3.Nioの紹介
NIOは、JDK1.4で提供される新しいAPIであるJavanewioの略語です。 Sunが公式に主張する特性は次のとおりです。
すべてのプリミティブタイプに(バッファ)キャッシュサポートを提供します。
キャラクターセットエンコードおよびデコードソリューション。
チャネル:新しいオリジナルのI/O抽象化。
ロックおよびメモリマップされたファイルのファイルアクセスインターフェイスをサポートします。
ブレイク、非ブロッキング、高度にスケーラブルなネットワークI/Oを提供します。
この記事では、これらの機能を学び、紹介します。
4.バッファー&シャネル
チャネルとバッファーはNIOであり、2つの最も基本的なデータ型の抽象化です。
バッファ:
それはメモリの連続ブロックです。
これは、NIOデータを読み書きするためのトランジットプレイスです。
チャネル:
データのソースまたはデータの宛先
バッファーにデータを提供したり、バッファデータ、バッファオブジェクトを読み取るためのユニークなインターフェイス。
非同期I/Oサポート
例1:copyfile.java:
パッケージサンプル; java.io.fileinputStream; Import java.io.fileoutputStream; Import java.nio.bytebuffer; import java.nio.channels.filechannel; public static void main(String [] args)Throws Exception {String Infile = "c:///copy.sql"; "c://copy.txt"; //ソースファイルとターゲットファイルの入力と出力ストリームを取得fileinputStream fin = new fileinputStream(file); fileoutputStream fout = new fileoutputStream(outfile); //入力および出力チャネルを取得FileChannel FCIN = Fin.GetChannel() bytebuffer buffer = bytebuffer.allocate(1024); while(true){//クリアメソッドはバッファをリセットして読み取りデータバッファーを受け入れることができます。別のチャネルバッファーにデータを新しく読み取ります。flip(); //出力チャネルからバッファーfcout.write(バッファ);}}}}にデータを書き込むバッファの内部構造は次のとおりです(次の図は情報からコピーされます):
図2:バッファー内部構造
バッファーは、主に3つの変数の位置、制限、容量によって読み取りおよび書き込みプロセスを制御します。これらの3つの変数の意味を次の表に示します。
パラメーター | 書き込みモード | 読み取りモード |
位置 | 現在書かれているユニットデータの数。 | 現在のユニットデータの場所が読み取られます。 |
制限 | これは、記述できるデータの最大数と容量が同じであることを表しています。 | これは、読み取ることができるデータの最大数を表します。これは、以前に記述された単位データの量と一致しています。 |
容量 | バッファ容量 | バッファ容量 |
一般的なバッファ方法:
flip():書き込みモードを読み取りモードに変換します
Rewind():位置を0にリセットします。これは、一般的に繰り返し読み取りに使用されます。
clear():バッファをクリアし、再び書き込みの準備をします(位置は0になり、制限は容量になります)。
compact():未読データをバッファーのヘッドにコピーします。
mark()、reset():マークは位置をマークでき、リセットはこの位置にリセットできます。
一般的なタイプのバッファ:bytebuffer、mappedbytebuffer、charbuffer、doublebuffer、floatbuffer、intbuffer、longbuffer、shortbuffer。
一般的なチャネル:FileChannel、DatagramChannel(UDP)、Socketchannel(TCP)、Serversocketchannel(TCP)
このマシンで簡単なパフォーマンステストが実行されました。私のラップトップは適度に機能します。 (特定のコードの添付ファイルを参照してください。Nio.sample.filecopyパッケージの以下の例を参照してください)以下は参照データです。
シナリオ1:370mファイルをコピーします
シナリオ2:3つのスレッドコピー同時に、各スレッドは370mファイルをコピーします。
シーン | FileInputStream+ fileoutputStream | FileInputStream+ BufferedInputStream+ fileoutputStream | bytebuffer+ FileChannel | mappedbytebuffer +fileChannel |
一時的なシーン(ミリ秒) | 25155 | 17500 | 19000 | 16500 |
シーン2時間(ミリ秒) | 69000 | 67031 | 74031 | 71016 |
5.Nio.Charset
文字エンコードとデコード:ByteCode自体はいくつかの数字であり、正しいコンテキストで正しく解析されます。データをByteBufferに保存するときは、文字セットのエンコード方法を考慮する必要があります。 ByteBufferデータを読んで表示するときは、文字セットを解読することが含まれます。
Java.nio.Charsetは、エンコードとデコードのための一連のソリューションを提供します。
最も一般的なHTTP要求を例にとると、リクエストは要求時に正しくコード化する必要があります。応答は、取得したときに正しくデコードする必要があります。
次のコードはBaiduにリクエストを送信し、表示の結果を取得します。この例は、チャーセットの使用を示しています。
例2baidureader.java
パッケージnio.readpage; import java.nio.bytebuffer;インポートjava.nio.channels.socketchannel; import java.nio.charset.charset; import java.net.inetsocketAddress; import java.io.ioexception; private charlset = private charset = private charset = private charset = private charset = private charset = private charset socketchannelチャンネル; public void readhtmlcontent(){try {inetsocketAddress socketaddress = new inetsocketAddress( "www.baidu.com"、80); // step1:接続チャネルを開きます= socketchannel.open(socketaddress); http/1.1 " +"/r/n/r/n "); // step3:data bytebuffer buffer = bytebuffer.allocate(1024); // 1024 -byteバッファーを読み取りますwhile(channel.read(buffer)!= -1){buffer.flip(); System.out.println(charset.decode(buffer)); // charset.decodeメソッドを使用してstring buffer.clear(); // clear buffer}} catch(system.err.println(e.tostring()); e){}}}} public static void main(string [] args){new baidureader()。readhtmlcontent();}}}6。非ブロッキングIO
非ブロッキングIOに関しては、ブロッキングの側面、非ブロッキング、非ブロッキング原則、非同期コアAPIの側面から理解します。
詰まりとは何ですか?
一般的なネットワークIO通信プロセスは次のとおりです。
このネットワーク通信プロセスから、ブロッキングが何であるかを理解しましょう。
接続が上記のプロセスに到着していない場合、Acceptはブロックされ、プログラムはここで実行した後にハングする必要があり、CPUは代わりに他のスレッドを実行します。
上記のプロセスでデータが準備ができていない場合、読み取りもブロックされます。
ブロッキングネットワークIOの機能:マルチスレッド複数の接続。各スレッドには独自のスタックスペースがあり、CPU時間をかけています。すべてのスレッドは、外部の準備ができていることに遭遇するとブロックされます。ブロッキングの結果、多数のプロセスコンテキストの切り替えにつながります。そして、ほとんどのプロセスコンテキストの切り替えは意味がない場合があります。たとえば、ポートのスレッドが耳を傾けると仮定し、1日にいくつかのリクエストしかありませんが、CPUはスレッドのコンテキストの切り替えを常に行う必要があり、切り替えのほとんどはブロッキングで終了します。
ノンブロッキングとは何ですか?
これが比phorです:
AからBまでのバスでは、道路上に降りる可能性のある多くのポイントがあります。ドライバーは、どのポイントがバスから降りるかわかりません。バスから降りる必要がある人にもっと対処する方法は?
1。プロセス中に、運転手は定期的に各乗客に目的地に到着したかどうかを尋ねます。誰かがそれを言うと、運転手は停止し、乗客が降ります。 (ブロッキングに似ています)
2。誰もがチケット売り手に目的地を伝え、その後眠ります。ドライバーはチケット売り手とのみ対話します。彼が特定の時点で到着すると、チケット売り手は乗客にバスを降りるように通知します。 (非ブロッキングと同様)
明らかに、目的地に到達するすべての人はスレッドと見なされ、ドライバーはCPUと見なすことができます。ブロッキングスタイルでは、各スレッドは、目的地を見つける結果を達成するために、コンテキストを常に投票し、切り替える必要があります。非ブロッキングモードでは、すべての乗客(スレッド)が睡眠(睡眠)であり、実際の外部環境の準備ができたときにのみ目覚めます。このようなウェイクアップは間違いなくブロックされません。
非ブロッキングの原則
プロセス全体を小さなタスクに切り替えて、タスク間のコラボレーションを通じて完了します。
専用のスレッドは、すべてのIOイベントを処理し、配布を担当します。
イベント駆動型メカニズム:イベントを同時に監視するのではなく、イベントが到着したときにトリガーします。
スレッド通信:スレッドは、待機、通知、その他の手段を通信します。すべてのコンテキストスイッチが理にかなっていることを確認してください。不必要なプロセススイッチングを減らします。
以下は、非同期IOの構造です。
原子炉は、チケット売り手の上記の比phor的な役割です。各スレッドの処理フローは、おそらくデータの読み取り、処理、エンコード、および応答の送信です。
非同期IOコアAPI
セレクタ
非同期IOのコアクラスは、1つ以上のチャネルでイベントを検出してイベントを配布できます。
選択されたスレッドを使用して、複数のチャネルでイベントをリッスンし、イベントドライバーに基づいて対応する応答をトリガーします。各チャネルにスレッドを割り当てる必要はありません。
SelectionKey
イベントのステータス情報と時間に対応するチャネルの結合が含まれています。
要約します
上記は、基本的なJavaの知識エッセイに関するこの記事の全体的な内容です。誰にとっても役立つことを願っています。興味のある友人は、このサイトの他の関連トピックを引き続き参照できます。欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました!