Java NIO中关于buffer.clear()的一点思路

在学习JavaNIO中看到关于Buffer的部分时提到buffer调用clear()方法不会真正的删除掉buffer中的数据,只是把position移动到最前面,同时把limit调整为capacity,忽然想到,如果不是真的删除掉buffer中的数据,那么如果之前写入buffer中五个字符:

CharBuffer buf = CharBuffer.allocate(48);
buf.put(new char[] {'a', 'b', 'c', 'd', 'e'});

但是只读取了一个:

System.out.println(buf.get());    // 此时输出为 a

如果这个时候clear一下,重新写入一个新的字符,再次读取第一个应该是我们新写入的字符:

buf.clear();
buf.put('g');
buf.flip();
System.out.println(buf.get());    // 此时输出为 g

如果此时之前的数据没有真的清除,那么应该可以继续读取上一次未读取的内容,这样的话就仅仅是从0位置覆盖原来的buffer进行写入,再次读取:

 System.out.println(buf.get());    // 预期输出为 b

此时理所当然的报了错:

g
java.nio.BufferUnderflowException
	at java.nio.Buffer.nextGetIndex(Buffer.java:500)
	at java.nio.HeapCharBuffer.get(HeapCharBuffer.java:135)
	at TestBuffer.main(TestBuffer.java:13)

实践后才想起来一个重点,当第二次写入新的字符时,要重新读取执行flip()方法时会将limit改为新的position,根本没有给我们机会(真的没机会吗?往后看...)去读buffer中的旧数据。

此时完整测试代码如下:

import java.nio.CharBuffer;

public class TestBuffer {
    public static void main(String[] args) {
        CharBuffer buf = CharBuffer.allocate(48);
        buf.put(new char[] {'a', 'b', 'c', 'd', 'e'});
        buf.flip();
        System.out.println(buf.get());
        buf.clear();
        buf.put('g');
        buf.flip();
        System.out.println(buf.get());
        System.out.println(buf.get());
    }
}

此时完整运行结果如下:

但是我们真的无法读取buffer中的旧数据了吗?

对此我查看源码后发现,limit竟然可以进行手动的设置:

可见limit可以设置为一个小于capacity且大于0的任意整数,为了读取到我们前面存的五个字符中剩下的四个,我们将limit改为5并读取5次,再次实验:

import java.nio.CharBuffer;

public class TestBuffer {
    public static void main(String[] args) {
        CharBuffer buf = CharBuffer.allocate(48);
        buf.put(new char[] {'a', 'b', 'c', 'd', 'e'});
        buf.flip();
        System.out.println(buf.get());
        buf.clear();
        buf.put('g');
        buf.flip();
        buf.limit(5);
        System.out.println(buf.get());    // 输出 g
        System.out.println(buf.get());    // 输出 b
        System.out.println(buf.get());    // 输出 c
        System.out.println(buf.get());    // 输出 d
        System.out.println(buf.get());    // 输出 e
    }
}

实验结果:

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值