Java-NIO學習小結
阿新 • • 發佈:2018-12-25
一、Java NIO概述
- Java NIO由如下三個核心部分組成:
- Channels 管道;負責連線TCP、UDP、File等進行資料的讀寫;管道每次讀寫資料都需要經過Buffers
- Buffers 緩衝區;負責接收管道讀取的資料/向管道傳輸資料;
- Selectors 選擇器;負責註冊的管道,並監聽管道的資料流動;呼叫select方法,會阻塞到管道中事件發生,返回後可以對這個事件進行處理
二、Channel
Java NIO的Channel與流類似,區別:流的讀寫是單向的,而管道的是雙工的,既可讀又可寫,不過在讀寫切換之前需要呼叫channel.flip()方法進行讀寫模式的切換。
而且 管道可以非同步的讀寫。Channel的重要實現:
- FileChannel:檔案讀寫
- DatagramChannle:UDP網路讀寫
- SocketChannel:TCP網路讀寫
- ServerSocketChannel:可以向Web伺服器一樣監聽新進來的TCP連線,然後對於每個連線建立響應的SocketChannel讀取其中的資料=
Channel通過Buffer進行資料讀寫的程式碼示例:
RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");//定義一個檔案 FileChannel inChannel = aFile.getChannel();//獲取檔案的管道
- Buffer 本質上是一塊兒可以寫入資料,又可以從中讀取資料的記憶體,被包裝成了NIO Buffer物件,並提供了一組方法來訪問該塊記憶體。
- capacity:緩衝區的容量
- position:位置指示器,初始值都為零。寫模式時,從零移動到capacity-1(或limit,即可用空間的限制)的地方,每寫入一個值就會,position都會移動到下一個可寫入位置的序號;從寫模式切換到讀模式時,position置零,然後開始移動,直到到上次寫入的最後序號limit(即切換時,limit=position)
- limit:可讀/寫的限制
Buffer的實現類
- ByteBuffer
- MappedByteBuffer
- CharBuffer
- DoubleBufferoatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
常用方法
- allocate(int capacity):初始化一個緩衝區,指定其大小
- put()
三、Scatter和Gather
分散(scatter)從Channel中讀取是指在讀操作時將讀取的資料寫入多個buffer中。因此,Channel將從Channel中讀取的資料“分散(scatter)”到多個Buffer中。
ByteBuffer header = ByteBuffer.allocate(128);
ByteBuffer body = ByteBuffer.allocate(1024);
ByteBuffer[] bufferArray = { header, body };
channel.read(bufferArray);
聚集(gather)寫入Channel是指在寫操作時將多個buffer的資料寫入同一個Channel,因此,Channel 將多個Buffer中的資料“聚集(gather)”後傳送到Channel。
ByteBuffer header = ByteBuffer.allocate(128);
ByteBuffer body = ByteBuffer.allocate(1024);
//write data into buffers
ByteBuffer[] bufferArray = { header, body };
channel.write(bufferArray);
注意buffer首先被插入到陣列,然後再將陣列作為channel.read() 的輸入引數。read()方法按照buffer在陣列中的順序將從channel中讀取的資料寫入到buffer,當一個buffer被寫滿後,channel緊接著向另一個buffer中寫。所以如果需要指定資料到指定的Channel中,必須使用資料的長度來定義相應Channel的容積