Java ByteBuffer用法總結

最近用SocketChannel進行網絡編程比較多,中間也遇到了幾個問題,出現的bug也主要來自於對於ByteBuffer的使用不當。如今終於調通了,對ByteBuffer及Socket網絡編程也有了更深的認識,特此總結一下。編程

對於ByteBuffer主要須要注意的是幾個標誌的含義:position,limit,capability,mark.幾個操做的影 響:flip(),clear(),rewind().還有就是在讀取或者寫入時,標誌的變化,好比get()方法致使position加1.數組

SocketChannel採用的是非阻塞異步讀取流數據,在讀取的時候,一般是網絡

  1. ByteBuffer.clear();
  2. SocketChannel.read(ByteBuffer);

若是流中有數據,就會把數據從position開始讀到ByteBuffer中,在讀取以前ByteBuffer的clear操做會把 position置爲0,limit置爲capability,也就是至關於清空了以前的內容,可是ByteBuffer中數組的內容在read以前是沒 有改變的.app

read以後,一般就是開始從ByteBuffer中提取讀到的數據,若是你的數據是以本身定義的數據包的格式進行發送的,那你還須要判斷是否讀到 了數據包的結尾,由於對流數據自己來講是沒有結尾這一說的。在提取數據以前,要先把position放到開始讀取時的位置,把limit放到當前位置,所 以要flip一下,表示從position到limit的位置都是須要的數據。異步

  1. ByteBuffer.flip();
  2. while(ByteBuffer.hasRemaining()){
  3. byte c=ByteBuffer.get();
  4. if(b == PACKAGE_END){
  5. //you can return the package here
  6. }else{
  7. //you can append the byte here.like StringBuilder.append().
  8. }
  9. }

這樣以來也存在一個問題,當一次讀到的ByteBuffer不包含完整的數據包或者包含多個數據包.那麼就須要在下一次繼續把這些包分拆出來.那麼在讀取數據的代碼處就能夠改成,這樣就把以前讀取到的未完整的包保留了下來:工具

  1. if(!ByteBuffer.hasRemaining){
  2. ByteBuffer.clear();
  3. SocketChannel.read(ByteBuffer);
  4. }

另一個可能會用到的操做就是ByteBuffer.rewind(),他會把position置爲0,limit保持不變,能夠用於重複讀取一段數據.ui

ByteBuffer是nio中一個很是方便的工具.設計思想也很是值得借鑑.spa

相關文章
相關標籤/搜索