NIO中的重要概念 通道、緩衝區、選擇器java
- 通道:相似於流,
- 可是能夠異步讀寫數據(流只能同步讀寫),
- 通道是雙向的,(流是單向的),
- 通道的數據老是要先讀到一個buffer 或者 從一個buffer寫入,
通道類型: 服務器
- FileChannel:從文件中讀寫數據。
- FileChannel比較特殊,
- 它能夠與通道進行數據交互,
- 不能切換到非阻塞模式,
- DatagramChannel:能經過UDP讀寫網絡中的數據。
- SocketChannel:能經過TCP讀寫網絡中的數據。
- 套接字通道(SocketChannel)能夠切換到非阻塞模式;
- ServerSocketChannel:能夠監聽新進來的TCP鏈接,像Web服務器那樣。
- 對每個新進來的鏈接都會建立一個SocketChannel。
緩衝區 - 本質上是一塊能夠存儲數據的內存,被封裝成了buffer對象而已!網絡
緩衝區類型:app
-
- ByteBuffer
- MappedByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
經常使用方法:異步
-
- allocate() - 分配一塊緩衝區
- put() - 向緩衝區寫數據
- get() - 向緩衝區讀數據
- flip() - 將緩衝區從寫模式切換到讀模式,limit 指向有效數據末尾
- rewind() - 將緩衝區從寫模式切換到讀模式,limit 指向capacity
- clear() - 從讀模式切換到寫模式,不會清空數據,
- 但後續寫數據會覆蓋原來的數據,
- 即便有部分數據沒有讀,也會被遺忘;
- compact() - 從讀數據切換到寫模式,數據不會被清空,
- 會將全部未讀的數據copy到緩衝區頭部,
- 後續寫數據不會覆蓋,而是在這些數據以後寫數據
- mark() - 對position作出標記,配合reset使用
- reset() - 將position置爲標記值
緩衝區的一些屬性:socket
- capacity - 緩衝區大小(容量),
- position - 寫數據時,position表示當前寫的位置,
- 每寫一個數據,會向下移動一個數據單元,
- 初始爲0;最大爲capacity - 1
- 切換到讀模式時,position會被置爲0,表示當前讀的位置
- limit - 寫模式下,limit 至關於capacity 表示最多能夠寫多少數據,
- 切換到讀模式時,limit 等於原先的position,表示最多能夠讀多少數據。
選擇器:至關於一個觀察者,spa
- 用來監聽通道感興趣的事件,
- 一個選擇器能夠綁定多個通道;
通道向選擇器註冊時,須要指定感興趣的事件,選擇器支持如下事件:rest
- SelectionKey.OP_READ表示關注讀數據就緒事件
- SelectionKey.OP_WRITE表示關注寫數據就緒事件
- SelectionKey.OP_CONNECT表示關注socket channel的鏈接完成事件
- SelectionKey.OP_ACCEPT表示關注server-socket channel的accept事件
若是你對不止一種事件感興趣,code
- 那麼能夠用「位或」操做符將常量鏈接起來,以下:
- int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE;
通道向選擇器註冊時,會返回一個 SelectionKey對象,具備以下屬性server
- interest集合
- ready集合
- Channel
- Selector
- 附加的對象(可選)
用「位與」操做interest 集合和給定的SelectionKey常量,
- 能夠肯定某個肯定的事件是否在interest 集合中。
- ready 集合是通道已經準備就緒的操做的集合。
- 在一次選擇(Selection)以後,你會首先訪問這個ready set。
- 能夠這樣訪問ready集合:
- int readySet = selectionKey.readyOps();
- 四個方法獲取已就緒事件,返回值爲boolean:
- 能夠將一個對象或者更多信息附着到SelectionKey上,
能夠經過選擇器的select方法獲取是否有就緒的通道;
- int select()
- int select(long timeout)
- int selectNow()