NIO目的是用來解決傳統IO的問題
NIO中的幾個基礎概念
- 通道(Channel):
傳統IO進行讀寫操作:
這裏的Stream相當於一個傳輸的通道。
傳統IO中,stream是單向的,如InputStream只能進行讀取操作,OutputStream只能進行寫操作。
NIO中,channel是雙向的,既可以用來進行讀取操作,又可以進行寫操作。
- Buffer(緩衝區)
在NIO中所有數據的讀寫都離不開Buffer。
- Selector(選擇器)
作用:用來輪詢每個註冊的Channel,一旦發現Channel有註冊的時間發生,便獲取事件然後進行處理。
用單線程處理一個selector,然後通過selector.select()方法來獲取到達事件,在獲取了到達事件之後,就可以逐個的對這些事件進行響應處理。
Channel
幾種常用的通道:
·FileChannel
·SocketChannel
·ServerSocketChannel
·DatagramChannel
通過使用FileChannel可以從文件讀或者向文件寫入數據;
通過SocketChannel,以TCP來向網絡連接的兩端讀寫數據;
通過ServerSocketChannel能夠監聽客戶端發起的TCP連接,併爲每個TCP連接創建一個新的SocketChannel來進行數據讀寫;
通過DatagramChannel,以UDP協議來向網絡連接的兩端讀寫數據。
Buffer
緩衝區,實際上是一個容器,是一個連續數組。Channel提供從文件、網絡讀取數據的渠道,但是讀取或寫入的數據必須經由Buffer,如下圖:
客戶端向服務端發送數據時,必須先將數據存入Buffer中,然後將Buffer中的內容寫入通道。服務端這邊接收數據必須通過Channel將數據讀入到Buffer中,然後再從Buffer中取出數據來處理。
在NIO中,Buffer是一個頂級父類,是一個抽象類,常用的Buffer的子類有:
·ByteBuffer
·IntBuffer
·CharBuffer
·LongBuffer
·DoubleBuffer
·DoubleBuffer
·FloatBuffer
·ShortBuffer
如果對於文件讀寫,上面的幾種Buffer都可能會用到。但是對於網絡讀寫來說,用到最多的是ByteBuffer。
Selector
Selector是NIO中的核心類,selector能夠檢測多個註冊的通達上是否有事件發生,如果有事件發生,便獲取事件然後針對每個事件進行相應的響應處理。這樣一來,只是用一個單線程就可以管理多個通道,也就是管理多個連接。這樣使得只有在連接真正有讀寫事件發生時,纔會調用函數來進行讀寫,就大大減少了系統的開銷,並且不必爲每個連接都創建一個線程,不用去維護多個線程,並且避免了多線程之間上下文切換導致的開銷。