高效NIO之Buffer

NIO介紹

Java NIO(New IO)是從Java 1.4版本開(kāi)始引入的一個(gè)新的IO API,可以替代標(biāo)準(zhǔn)的Java IO API。

  • Channels and Buffers(通道和緩沖區(qū)):標(biāo)準(zhǔn)的IO基于字節(jié)流和字符流進(jìn)行操作的,而NIO是基于通道(Channel)和緩沖區(qū)(Buffer)進(jìn)行操作,數(shù)據(jù)總是從通道讀取到緩沖區(qū)中,或者從緩沖區(qū)寫入到通道中。

本文主要介紹ByteBuffer的常用方法

  • Buffer 以下實(shí)現(xiàn)
    • ByteBuffer
    • CharBuffer
    • DoubleBuffer
    • FloatBuffer
    • IntBuffer
    • LongBuffer
    • ShortBuffer

一、首先介紹三個(gè)參數(shù)

image.png
  • capacity
  • position
  • limit
 String text = "123456789";                                                            
 ByteBuffer byteBuffer = ByteBuffer.allocate(15);                                      
 byteBuffer.put(text.getBytes());//將text復(fù)制到緩沖區(qū)                                         
 //TODO 開(kāi)始都去緩沖區(qū),如果不進(jìn)行flip,那么預(yù)測(cè),byteBuffer lim=15,pos=9,cap=15                          
 System.out.println(byteBuffer);//java.nio.HeapByteBuffer[pos=9 lim=15 cap=15]         
 //雖然pos等于9但是因?yàn)樗饕菑?開(kāi)始的,那么在預(yù)測(cè)pos 8為止等于上面text的9                                         
 System.out.println("預(yù)測(cè)pos 8為止等于:" + (char) byteBuffer.get(8));//預(yù)測(cè)成功:預(yù)測(cè)pos 8為止等于:9    

FIXME 由此解釋:position limit capacity

  1. position在未寫入數(shù)據(jù)時(shí)候?yàn)?,當(dāng)寫入數(shù)據(jù),就變?yōu)閷懭霐?shù)據(jù)長(zhǎng)度的下一個(gè)可寫的位置

text最后一個(gè)數(shù)的索引位置是8,所以在byteBuffer中position下一個(gè)可以寫的位置就是9,而8位置,就對(duì)應(yīng)了text中最后一個(gè)數(shù)9

  1. capacity等于緩沖區(qū)的長(zhǎng)度
  2. limit可以理解為寫入數(shù)據(jù)的長(zhǎng)度,當(dāng)初始化沒(méi)有數(shù)據(jù)時(shí)候,就等于capacity的長(zhǎng)度。而當(dāng)寫入數(shù)據(jù)時(shí)候就變成了數(shù)據(jù)的長(zhǎng)度

當(dāng)讀到這里,就可以對(duì)預(yù)測(cè)的明白了。

二、開(kāi)始新的高級(jí)學(xué)習(xí),讀寫操作

  1. flip(); 這個(gè)方法用于重置pos位置當(dāng)寫的時(shí)候位置為可寫的位置,但是讀的時(shí)候如果不重置,讀取的就是沒(méi)有數(shù)據(jù)的位置.用于讀寫轉(zhuǎn)換
 String text = "123456789";                                                    
 ByteBuffer byteBuffer = ByteBuffer.allocate(15);                              
 byteBuffer.put(text.getBytes());//將text復(fù)制到緩沖區(qū)        

 //開(kāi)始讀取
 //我們要從0開(kāi)始讀,到lim位置,而這個(gè)方法就是把pos=0,lim=數(shù)據(jù)長(zhǎng)度                                         
 byteBuffer.flip();//預(yù)測(cè):pos=0,lim=9,cap=15                                        
 System.out.println(byteBuffer);//java.nio.HeapByteBuffer[pos=0 lim=9 cap=15]     
 for (int i = 0; i < byteBuffer.limit(); i++) {                                   
     System.out.print((char) byteBuffer.get(i));//123456789                       
 }                                             

假設(shè)不進(jìn)行flip就會(huì)讀空數(shù)據(jù),那么由于我們轉(zhuǎn)為char 所以出來(lái)就是亂碼123456789[][][]

  1. clear();這個(gè)方法會(huì)把pos=0 lim=15 cap=15,等于把byteBuffer對(duì)象重置了
byteBuffer.clear();                                                   
System.out.println(byteBuffer);          
  1. rewind();這個(gè)方法會(huì)重置pos=0 其他維持原樣 為讀取有效數(shù)據(jù)
  2. get();獲得最后limit位置數(shù)據(jù)
  3. get(int index);獲取制定位置數(shù)據(jù)
  4. get(byte arr);復(fù)制有效數(shù)據(jù)到arr數(shù)組
  5. put(byte arr);把a(bǔ)rr數(shù)據(jù)寫入到緩沖區(qū)
  6. put(int index,byte arr);把a(bǔ)rr寫入到指定位置

三、 標(biāo)記方法,具有回滾功能,這兩個(gè)方法不解釋,只演示

  1. mark();
  2. reset();
 byteBuffer.put(text.getBytes());//因?yàn)樯厦嬉呀?jīng)清理了,所以在此將text復(fù)制到緩沖區(qū)                  
 for (int i = 0; i < 8; i++) {                                                
     if (i == 1) {                                                            
         byteBuffer.mark();//標(biāo)記1位置開(kāi)始寫新數(shù)據(jù)                                      
         byteBuffer.put(1, ((byte) '4'));//此時(shí)預(yù)測(cè)數(shù)據(jù)為:143456789                  
     }                                                                        
 }                                                                            
 //    byteBuffer.reset();//回到標(biāo)記位置                                            
 byteBuffer.flip();                                                           
 for (int i = 0; i < byteBuffer.limit(); i++) {                               
     System.out.print((char) byteBuffer.get(i));//143456789 ,預(yù)測(cè)成功             
 }                                                                            

四、復(fù)制緩沖區(qū)

byteBuffer.clear();                                                              
byteBuffer.put(text.getBytes());//將text復(fù)制到緩沖區(qū)                                    
ByteBuffer byteBuffer1 = byteBuffer.duplicate();                                 
System.out.println(byteBuffer);   //[pos=9 lim=15 cap=15]                        
System.out.println(byteBuffer1);  //[pos=9 lim=15 cap=15]                        
//但是當(dāng)修改一個(gè)地方,另一個(gè)緩沖區(qū)也會(huì)變化 ,這個(gè)變化是內(nèi)容變化,但是pos lim cap不改變                               
//開(kāi)始試驗(yàn),將1的插入新數(shù)據(jù)                                                                  
byteBuffer1.flip();      //重置寫                                                   
byteBuffer1.put((byte) 'A');                                                     
System.out.println(byteBuffer);       //[pos=9 lim=15 cap=15]                    
System.out.println(byteBuffer1);     //[pos=10 lim=15 cap=15]  因?yàn)樘砑恿?,所以pos位置變了   
//開(kāi)始獲取,這個(gè)兩個(gè)最后一個(gè)數(shù)據(jù),預(yù)測(cè),都是A。                                                        
System.out.println((char) byteBuffer.get(0));   //A                              
System.out.println((char) byteBuffer1.get(0));  //A                              

此方法有個(gè)特殊的地方就是:當(dāng)修改一個(gè)地方,另一個(gè)緩沖區(qū)也會(huì)變化 ,這個(gè)變化是內(nèi)容變化,但是pos lim cap不改變

附錄

  • NIO是高效的IO處理方式,如果感興趣的筆者推薦可以和筆者一起深入學(xué)習(xí)Netty框架,快速開(kāi)發(fā)高性能、高可靠性的網(wǎng)絡(luò)服務(wù)器和客戶端程序
  • 其次Buffer的使用方法遠(yuǎn)不止如此,筆者這里只使用常用方法
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)自 http://www.ibm.com/developerworks/cn/education/java/j-...
    抓兔子的貓閱讀 2,496評(píng)論 0 22
  • Java NIO(New IO)是從Java 1.4版本開(kāi)始引入的一個(gè)新的IO API,可以替代標(biāo)準(zhǔn)的Java I...
    JackChen1024閱讀 7,948評(píng)論 1 143
  • ChannelChannel CharacteristicsJava NIO Channel Classesbuf...
    六尺帳篷閱讀 4,079評(píng)論 2 28
  • 前言: 之前的文章《Java文件IO常用歸納》主要寫了Java 標(biāo)準(zhǔn)IO要注意的細(xì)節(jié)和技巧,由于網(wǎng)上各種學(xué)習(xí)途徑,...
    androidjp閱讀 3,242評(píng)論 0 22
  • 引言:NIO是Java面試中老生常談的一個(gè)話題,No-Block-IO(非阻塞IO);今天?;艘惶鞎r(shí)間將并發(fā)變成...
    cp_insist閱讀 580評(píng)論 0 0

友情鏈接更多精彩內(nèi)容