NIOプログラミングベース
6834 ワード
IOとNIOの違い:その本質は閉塞と非閉塞の違いである.ブロックの概念:アプリケーションはネットワークデータを取得する際に、ネットワーク転送データが遅い場合、転送が完了するまで待機します.非ブロックコンセプト:アプリケーションは、待機する必要がなく、準備ができているデータを直接取得できます.IOは同期閉塞形態であり、NIOは非同期閉塞形態であり、NIO病はJDK 1で非同期を実現する.7後にNIOライブラリパッケージをアップグレードし、非同期非ブロック同期モデルNIO 2をサポートする.0; IOモード:同期ブロックモードIO、サーバ実装モードは1つの接続スレッドであり、すなわちクライアントが接続要求がある場合、サーバは1つのスレッドを起動して処理する必要があり、この接続が何もしなければ不要なスレッドオーバーヘッドをもたらし、もちろんスレッドプールメカニズムを通じて改善することができる.NIO:非ブロックIOを同期し、サーバ実装モードはクライアントから送信されたリクエストがマルチプレクサに登録されるスレッドを要求し、マルチプレクサはIOリクエストが接続されているときに1つのスレッドを起動して処理する.AIO:非同期非ブロックIO、サーバ実装モードは1つの有効な要求1つのスレッドであり、クライアントのIO要求はすべてOSが先に完成してからサーバアプリケーションにスレッドを起動して処理することを通知する.同期すると、アプリケーションはIOの読み書き操作に直接関与し、アプリケーションはデータの準備が整うまで、またはポーリングポリシーを使用して準備完了ステータスをリアルタイムでチェックし、準備が整うとデータを取得するまで、メソッドに直接ブロックされます.非同期の場合、すべてのIO読み書きチュートリアルオペレーティングシステムは、私たちのアプリケーションとは関係なく、私たちのプログラムはIO読み書きに関係する必要はありません.システムが終了した場合、IO読み書き操作を要求すると、私たちのアプリケーションに通知を送信しますか.私たちのアプリケーションは直接データを持って行けばいいです.ブレークポイントの継続:マルチスレッドにファイルの接合を加えて構成されています.Bufferバッファの使用方法:バッファの読み書き操作を実現する:
markとrestの使い方の違い:タグ:markと再作成rest:タグはインデックスであり、Bufferのmark()メソッドの特定のposiotionを通じて、その後reset()メソッドでこのpositionを復元することができます.
キャッシュは直接キャッシュ領域と非直接キャッシュ領域に分けられます.非直接キャッシュ領域は主にjvmキャッシュ領域に格納され、直接キャッシュ領域は主に物理メモリに格納されます.物理メモリに格納する方が効率的です.非直接キャッシュ領域はより安全です.ダイレクトバイトバッファは、このようなallocateDirect()ファクトリメソッドを呼び出すことによって作成できます.チャネル(Channel)の原理の取得:チャネル表示はIOデバイスに開く(例:ファイル、ソケット)の接続は、NIOシステムを使用する必要がある場合、IOデバイスに接続するためのチャネルとデータを格納するためのキャッシュ領域を取得し、キャッシュ領域を操作してデータを処理し、Channelは転送を担当し、Bufferは値を割り当てて格納し、チャネルはJava.io.channelsパケットで定義されたChannleはIOソースとターゲットが開いている接続を表す.Channleは転送と似ている.統合されたストリームは、チャネル自体がデータに直接アクセスできないだけで、ChannleはBufferと対話するしかありません.Java.nio.channels.Channelインタフェース:
取得チャネル:1.Javaはサポートチャネルのクラスに対してgetChannel()メソッドローカルio:FileInputStream/FileOutPutStream()RandomAccessFile()ネットワークIO:Socket:Server Socket:DataGramSocket:2を提供する.JDK 1.7中NIO.2各チャネルに対して静的な方法open()3を提供する.JDK 1.7中NIO.2-2 Filesツール類のnewByteChannel()
分散読み込み:チャネル内のデータを複数のバッファに分散します.≪集計書込み|Aggregate Write|oem_src≫:複数のキャッシュ領域のデータをチャネルに集計します.
@Test
public void test01(){
// buffer 。
allocate = ByteBuffer.allocate(1024);
System.out.println("=======>>>>>> :"+ allocate.limit());
System.out.println("==========>>>> :"+ allocate.position());
System.out.println("==========>>>>> :"+ allocate.capacity());
System.out.println("==========>>>> :");
allocate.put("1234567".getBytes());
System.out.println("=======>>>>>> :"+ allocate.limit());
System.out.println("==========>>>> :"+ allocate.position());
System.out.println("==========>>>>> :"+ allocate.capacity());
allocate.flip();//
byte [] bytes = new byte[allocate.limit()];
allocate.get(bytes);
System.out.println("==========>>>>>> :"+new String(bytes,0,bytes.length));
System.out.println("==========>>>>>>> ");
allocate.rewind();//
byte [] bytes1 = new byte[allocate.limit()];
allocate.get(bytes1);
System.out.println("==========>>>>>> :"+new String(bytes1,0,bytes1.length));
System.out.println(" :"+allocate.clear());
System.out.println("=======>>>>>> :"+ allocate.limit());
System.out.println("==========>>>> :"+ allocate.position());
System.out.println("==========>>>>> :"+ allocate.capacity());
System.out.println((char)allocate.get());
}
markとrestの使い方の違い:タグ:markと再作成rest:タグはインデックスであり、Bufferのmark()メソッドの特定のposiotionを通じて、その後reset()メソッドでこのpositionを復元することができます.
@Test
public void test02(){
ByteBuffer byteBuffer =ByteBuffer.allocate(10);// ,Byte 10,
byteBuffer.put("abcdefg".getBytes());
byteBuffer.flip();//
byte [] bytes = new byte[byteBuffer.limit()];
byteBuffer.get(bytes,0,2);
byteBuffer.mark();//
System.out.println(new String (bytes,0,2));
System.out.println(byteBuffer.position());
System.out.println("===============>>>>>>>>>");
byteBuffer.get(bytes,2,2);
System.out.println(new String(bytes,0,2));
byteBuffer.reset();// mark
System.out.println(byteBuffer.position());
}
キャッシュは直接キャッシュ領域と非直接キャッシュ領域に分けられます.非直接キャッシュ領域は主にjvmキャッシュ領域に格納され、直接キャッシュ領域は主に物理メモリに格納されます.物理メモリに格納する方が効率的です.非直接キャッシュ領域はより安全です.ダイレクトバイトバッファは、このようなallocateDirect()ファクトリメソッドを呼び出すことによって作成できます.チャネル(Channel)の原理の取得:チャネル表示はIOデバイスに開く(例:ファイル、ソケット)の接続は、NIOシステムを使用する必要がある場合、IOデバイスに接続するためのチャネルとデータを格納するためのキャッシュ領域を取得し、キャッシュ領域を操作してデータを処理し、Channelは転送を担当し、Bufferは値を割り当てて格納し、チャネルはJava.io.channelsパケットで定義されたChannleはIOソースとターゲットが開いている接続を表す.Channleは転送と似ている.統合されたストリームは、チャネル自体がデータに直接アクセスできないだけで、ChannleはBufferと対話するしかありません.Java.nio.channels.Channelインタフェース:
FileChannel:
SocketChannel:
ServerSocketChannel:
DatagramChannel:
取得チャネル:1.Javaはサポートチャネルのクラスに対してgetChannel()メソッドローカルio:FileInputStream/FileOutPutStream()RandomAccessFile()ネットワークIO:Socket:Server Socket:DataGramSocket:2を提供する.JDK 1.7中NIO.2各チャネルに対して静的な方法open()3を提供する.JDK 1.7中NIO.2-2 Filesツール類のnewByteChannel()
@Test
public void test03()throws Exception{
//
FileInputStream fileInputStream = new FileInputStream("/Users/yantianpeng/Desktop/11.png");
//
FileOutputStream fileOutputStream = new FileOutputStream("/Users/yantianpeng/Desktop/2.png");
//
FileChannel channel = fileInputStream.getChannel();
//
FileChannel channel1 = fileOutputStream.getChannel();//
//
ByteBuffer allocate = ByteBuffer.allocate(1024);
while (channel.read(allocate)!=-1){
//
allocate.flip();
channel1.write(allocate);
allocate.clear();//buffer clear
}
channel1.close();
channel.close();
fileOutputStream.close();
fileOutputStream.close();
}
分散読み込み:チャネル内のデータを複数のバッファに分散します.≪集計書込み|Aggregate Write|oem_src≫:複数のキャッシュ領域のデータをチャネルに集計します.
/**
* : 。
* : 。
*/
@Test
public void test05() throws Exception{
//
RandomAccessFile randomAccessFile = new RandomAccessFile("/Users/yantianpeng/Desktop/1.txt", "rw");
//
FileChannel channel = randomAccessFile.getChannel();
//
ByteBuffer allocate1 = ByteBuffer.allocate(100);
ByteBuffer allocate2 = ByteBuffer.allocate(1024);
ByteBuffer [] bufs= {allocate1,allocate2};
channel.read(bufs);
for (ByteBuffer byteBuffer: bufs) {
byteBuffer.flip();//
}
String string =new java.lang.String(bufs[0].array(),0,bufs[0].limit());
System.out.println(string);
System.out.println("=======================================");
System.out.println(new String(bufs[1].array(),1,bufs[1].limit()));
System.out.println("==========>>>>>>>>>>> ");
RandomAccessFile randomAccessFile1 = new RandomAccessFile("/Users/yantianpeng/Desktop/2.txt ", "rw");
//
FileChannel channel1 = randomAccessFile1.getChannel();
channel1.write(bufs);
randomAccessFile1.close();
randomAccessFile.close();
}