bytebuffer读写数据,nio使用时读到上一次的数据

首先看一组代码

        ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
        writeBuffer.put(new String("大话西游").getBytes());
        System.out.println(new String(writeBuffer.array()));
        writeBuffer.clear();
        System.out.println(new String(writeBuffer.array()));

输出结果

大话西游
大话西游

writeBuffer.array()-》返回整个数组
由此可知bytebuffer的clear方法不会清除数据,那么bytebuffer.clear()做了哪些事,
1.position(当前位置)被设置为0(起始位置)。
2.limit被设置为capacity,也就是数据的长度限制被设置为数组长度。
其数据并没有被清空,
此时调用array方法,他会重新去读,则为上述输出。


nio中多次使用bytebuffer读写及clear

再看一组nio中模拟多次用同一bytebuffer读写的代码

   writeBuffer.put(new String("大话西游111").getBytes());
        System.out.println(new String(writeBuffer.array()));
        writeBuffer.clear();
        writeBuffer.put(new String("紫霞").getBytes());
        System.out.println(new String(writeBuffer.array()));
        writeBuffer.compact();
        System.out.println(new String(writeBuffer.array()));
        writeBuffer.clear();
        System.out.println(new String(writeBuffer.array()));
        writeBuffer.clear();
        writeBuffer.compact();
        System.out.println(new String(writeBuffer.array()));

输出

大话西游111                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
紫霞西游111  
西游111      
西游111   
西游111                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      

1.writeBuffer.array()//返回支持此操作的字节数组
直接返回 “大话西游111”
2.当调用clear方法时,所有指针复位position-0,limit-capacity。
此时写入紫霞,position向后移动4个字节(gb2312),于是前面的大话两个字被取代,
调用
输出“紫霞西游111”。而此时读取到的位置应该为而此时limit的位置位于“霞”,
3.调用compact方法,则把limit-position的数据移动到0-position,同时position置为0。即“紫霞”两个字被覆盖,返回为“西游111”
4、同理,5同理


bytebuffer正确读写

1.封装读,调用get方法会使position向后移动。

public static void print(ByteBuffer writeBuffer) {
    
    
        int limit = writeBuffer.limit();
        byte[] bs=new byte[limit];
        int i=0;
        while (writeBuffer.hasRemaining()){
    
    
            bs[i++]=writeBuffer.get();
        }
        System.out.println(new String(bs));
    }

writeBuffer.hasRemaining()为postion-limt是否还有内容

2.读之前调用flip(),把limit指向position,position指向0。
写之前调用clear,把postion指向0

        ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
        writeBuffer.clear();
        writeBuffer.put(new String("大话西游111").getBytes());
        writeBuffer.flip();
        print(writeBuffer);
        writeBuffer.clear();
        writeBuffer.put(new String("紫霞").getBytes());
        //等同writeBuffer.flip();
//        writeBuffer.limit(writeBuffer.position());
//        writeBuffer.position(0);
        writeBuffer.flip();
        print(writeBuffer);

输出

大话西游111
紫霞

实际上调用writeBuffer.array()会发现内容还是“紫霞西游111 ”但是我们只会读写入的部分。所以只有紫霞读出来了。
另外注意:
chanel.read(buffer),表示把数据从chanel写到buffer对于buffer是写操作,应该先调用buffer.clear().
chanel.writer(buffer),表示把数据buffer写到chanel,对于buffer是读操作,应该先调用flip().
chanel从buffer读数据只会读到limit

猜你喜欢

转载自blog.csdn.net/qq_27275851/article/details/113366936