1. 程式人生 > >Java的NIO之Channel通道

Java的NIO之Channel通道

1.Channel 通道的簡介

java的NIO的通道類似流,但是又有一些不同:
- 既可以從Channel中讀資料也可以往Channel裡面寫資料;但是流的讀寫一般是單向的。
- Channel可以非同步的讀寫;
- Channel的讀寫是通過Buffer這個中介實現的。資料總是要先讀到一個Buffer,或者總是要從一個Buffer中寫入。如下圖所示:

NIO的channel

引用一段關於描述Channel的文字:

其中Channel對應以前的流,Buffer不是什麼新東西,Selector是因為NIO可以使用非同步的非堵塞模式才加入的東西。

以前的流總是堵塞的,一個執行緒只要對它進行操作,其它操作就會被堵塞,也就相當於水管沒有閥門,你伸手接水的時候,不管水到了沒有,你就都只能耗在接水(流)上。

NIO的Channel的加入,相當於增加了水龍頭(有閥門),雖然一個時刻也只能接一個水管的水,但依賴輪換策略,在水量不大的時候,各個水管裡流出來的水,都可以得到妥善接納,這個關鍵之處就是增加了一個接水工,也就是Selector,他負責協調,也就是看哪根水管有水了的話,在當前水管的水接到一定程度的時候,就切換一下:臨時關上當前水龍頭,試著開啟另一個水龍頭(看看有沒有水)。

當其他人需要用水的時候,不是直接去接水,而是事前提了一個水桶給接水工,這個水桶就是Buffer。也就是,其他人雖然也可能要等,但不會在現場等,而是回家等,可以做其它事去,水接滿了,接水工會通知他們。
這其實也是非常接近當前社會分工細化的現實,也是統分利用現有資源達到併發效果的一種很經濟的手段,而不是動不動就來個並行處理,雖然那樣是最簡單的,但也是最浪費資源的方式。
上面的比方還是相當清晰的描述了Channel、Buffer和Selector的作用。

2.Channel的最重要的幾個實現以及使用場景

下面是Java的NIO的最重要的幾個channel的實現:
1. FileChannel 主要是用於檔案的讀寫
2. DatagramChannel 主要用於UDP讀寫網路中的資料
3. SocketChannel 通過TCP讀寫網路中的資料。
4. ServerSocketChannel 主要用於服務端:可以監聽新進來的TCP連線,像Web伺服器那樣。對每一個新進來的連線都會建立一個SocketChannel。

3. 一個FileChannel的基本例項;

RandomAccessFile accessFile = new
RandomAccessFile("data.txt", "rw"); FileChannel inchannel = accessFile.getChannel();//獲取 FileChannel ByteBuffer buffer = ByteBuffer.allocate(48);//申請48位元組的緩衝區 int bytesRead = inchannel.read(buffer);// 讀取資料放入緩衝區 while(bytesRead != -1){ System.out.println("read " + bytesRead); Thread.sleep(500); buffer.flip(); bytesRead=-1; } while(buffer.hasRemaining()){ System.out.print((char) buffer.get()); } buffer.clear(); bytesRead = inchannel.read(buffer); accessFile.close();