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之前是沒 有改變的.

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保持不變,可以用於重復讀取一段數據.

ByteBuffer是nio中一個非常方便的工具.設計思想也非常值得借鑒.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM