1. 程式人生 > >解析NIO中Buffer的position和limit關係

解析NIO中Buffer的position和limit關係

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