解析NIO中Buffer的position和limit关系

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liyantianmin/article/details/83957634
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

猜你喜欢

转载自blog.csdn.net/liyantianmin/article/details/83957634
今日推荐