解析NIO中Buffer的position和limit關係
阿新 • • 發佈:2018-12-20
public class TestNio { public static void main(String[] args) throws Exception { FileInputStream file = new FileInputStream("src/nio_test_value.txt"); FileChannel channel = file.getChannel(); //初始化Buffer的長度為5,即使檔案裡面有多個元素,也只能讀5個數據 ByteBuffer byBuf = ByteBuffer.allocate(5); //buff的pos從0開始,limit是allocate初始化大小的(由於buf下表是從0開始的)5,channel的pos表示通道里面的檔案讀取資料的位置,也為0 System.out.println("step1: byBufPosition:"+byBuf.position()+",byBufLimit:"+byBuf.limit()+",channelPosition:"+channel.position()); //channel讀取資料,即往Buffer裡面寫資料 channel.read(byBuf); //在Buffer裡面寫完5個數據之後,buff的pos位置是5,byLimit的位置仍然是原來的位置5,由於讀取檔案讀到了5個元素,所以chnanle的pos是5. System.out.println("step2: byBufPosition:"+byBuf.position()+",byBufLimit:"+byBuf.limit()+",channelPosition:"+channel.position()); //將Buff的寫狀態轉換為讀狀態,重置pos和limit,但是和channel沒有關係。並沒有重置channel byBuf.flip(); //重置後,從0開始讀取,最大可讀的數量為5(裡面只有5個元素),channel的pos不變 System.out.println("step3: byBufPosition:"+byBuf.position()+",byBufLimit:"+byBuf.limit()+",channelPosition:"+channel.position()); while(byBuf.remaining()>0){ byte b = byBuf.get(); System.out.println("Chanrset:"+(char)b); } //讀取完之後Buf的pos及limit移動值 System.out.println("step4: byBufPosition:"+byBuf.position()+",byBufLimit:"+byBuf.limit()+",channelPosition:"+channel.position()); //再次重置,將Buf的讀轉換為往Buff裡面寫. byBuf.flip(); //buff的pos被重置為0,buf的Limit被重置為上次最大可讀取資料的位置,即step4的pos位置,由於和channel沒有關係。所以channel的pos不變認為5 System.out.println("step5: byBufPosition:"+byBuf.position()+",byBufLimit:"+byBuf.limit()+",channelPosition:"+channel.position()); //在此讀取資料,即往Buff裡面寫資料 channel.read(byBuf); //由於channel的pos是5,裡面有8個元素,上次讀了5個剩餘3個,所以在讀完之後,pos的位置是3,,limit仍然保留上次的值5,channel的位置移動,移動到8 System.out.println("step6: byBufPosition:"+byBuf.position()+",byBufLimit:"+byBuf.limit()+",channelPosition:"+channel.position()); byBuf.flip(); //由Buff的寫資料轉換為讀資料,buf的pos被初始化為0,,limit被設定為最大可讀取的位置,即step6的pos配置3.channel的pos是8 System.out.println("step7: byBufPosition:"+byBuf.position()+",byBufLimit:"+byBuf.limit()+",channelPosition:"+channel.position()); while(byBuf.remaining()>0){ byte b = byBuf.get(); System.out.println("Chanrset:"+(char)b); } //通過step4--step5和step6--step7可看出buf的limi是上一次pos的位置,不管是讀還是寫。即將要讀或者寫的最後一個元素的下一個元素的索引位置 channel.close(); } }
輸出
step1: byBufPosition:0,byBufLimit:5,channelPosition:0 step2: byBufPosition:5,byBufLimit:5,channelPosition:5 step3: byBufPosition:0,byBufLimit:5,channelPosition:5 Chanrset:a Chanrset:b Chanrset:c Chanrset:d Chanrset:f step4: byBufPosition:5,byBufLimit:5,channelPosition:5 step5: byBufPosition:0,byBufLimit:5,channelPosition:5 step6: byBufPosition:3,byBufLimit:5,channelPosition:8 step7: byBufPosition:0,byBufLimit:3,channelPosition:8 Chanrset:1 Chanrset:2 Chanrset:3