註意:轉載自併發編程網 – ifeve.com本文鏈接地址: Java NIO系列教程(二) Channel Channel Java NIO的通道類似流,但又有些不同: 既可以從通道中讀取數據,又可以寫數據到通道。但流的讀寫通常是單向的。 通道可以非同步地讀寫。 通道中的數據總是要先讀到一個Buff ...
註意:轉載自併發編程網 – ifeve.com本文鏈接地址: Java NIO系列教程(二) Channel
Channel
Java NIO的通道類似流,但又有些不同:
- 既可以從通道中讀取數據,又可以寫數據到通道。但流的讀寫通常是單向的。
- 通道可以非同步地讀寫。
- 通道中的數據總是要先讀到一個Buffer,或者總是要從一個Buffer中寫入。
正如上面所說,從通道讀取數據到緩衝區,從緩衝區寫入數據到通道。如下圖所示:
一、Channel的實現
這些是Java NIO中最重要的通道的實現:
- FileChannel
- DatagramChannel
- SocketChannel
- ServerSocketChannel
FileChannel 從文件中讀寫數據。
DatagramChannel 能通過UDP讀寫網路中的數據。
SocketChannel 能通過TCP讀寫網路中的數據。
ServerSocketChannel可以監聽新進來的TCP連接,像Web伺服器那樣。對每一個新進來的連接都會創建一個SocketChannel。
二、基本的 Channel 示例
下麵是一個使用FileChannel讀取數據到Buffer中的示例:
public class Channel1 { public static void main(String[] args) { try { RandomAccessFile raf = new RandomAccessFile("./.gitignore","rw"); FileChannel channel = raf.getChannel(); //獲取通道 ByteBuffer bf = ByteBuffer.allocate(50); //通過靜態allocate方法創建一個緩衝區,容量為50 byte[] bytes = new byte[]{}; bytes = "123".getBytes(); bf = ByteBuffer.wrap(bytes); //通過靜態wrap方法,byte數組生成緩衝區,緩衝區中保留了原數據 while(bf.hasRemaining()){ System.out.print((char) bf.get()); } int bytesRead ; while ((bytesRead = channel.read(bf)) != -1) { //將通道中的數據寫入緩衝區,並判斷通道中的數據是否到末尾 System.out.println("Read " + bytesRead); bf.flip(); //反轉緩衝區 實際上就是將position置為0 後續buffer詳細介紹 while(bf.hasRemaining()){ //判斷緩衝區中是否還有值 System.out.print((char) bf.get()); //輸出緩衝區中的值 } bf.clear(); //清理緩衝區 } raf.close(); //關閉RandomAccessFile } catch (IOException e) { e.printStackTrace(); } } }
註意 buf.flip() 的調用,首先讀取數據到Buffer,然後反轉Buffer,接著再從Buffer中讀取數據。下一節會深入講解Buffer的更多細節