美文网首页
JAVA NIO中的ByteBuffer

JAVA NIO中的ByteBuffer

作者: 爱蛇 | 来源:发表于2018-01-11 11:37 被阅读0次

    ByteBuffer 主要有以下属性

    capacity

    容量大小,表示最多可存放Byte 的数量

    position

    操作指针,当下一次调用get或put 时就会从这里读取,换句话说,每put/get一次,position就会递增一次。

    limit

    表示缓存区里 "有效" 的元素长度,
    比如 ByteBuffer的容量capacity设置为10,那么这个10个字节默认都为0(表示无数值)
    而limit 的作用则表示10个字节里有多少个字节是有效的。
    假如往buffer put进5个字节,则limit为5.

    ByteBuffer 主要的方法

    clear() -- 主要用于在准备写入数据之前调用

    清除Buffer里面的数据,即将所有字节清零,limit设置为0,position设置为0
    每次读满buffer,准备要读下一次之前应该要清零,要不因为buffer满了而导致不能继续读。
    源码:

    public final Buffer clear() {
            position = 0;
            limit = capacity;
            mark = -1;
            return this;
     }
    

    flip() -- 主要用于写(即调用put方法)完数据后准备读(即调用get方法)

    用于记录当前position位置(修改limit来记录当前有效字节位置),并将position清0。
    源码:

    public final Buffer flip() {
            limit = position;
            position = 0;
            mark = -1;
            return this;
    }
    

    reset() -- 主要用于循环读取buffer的数据使用

    将当前position指针移动到上次调用mark()方法进行记录的位置
    例如广播同一条消息给不同的客户端
    源码:

     public final Buffer reset() {
            int m = mark;
            if (m < 0)
                throw new InvalidMarkException();
            position = m;
            return this;
    }
    

    mark() -- 主要用于准备reset之前使用

    记录当前position位置,等待下次reset时使用
    源码:

    public final Buffer mark() {
            mark = position;
            return this;
    }
    

    当往buffer里put 完一次数据以后,position 跟limit 都会同时递增,基本是同步,
    假如put 了10个字节,position跟limit 从0 开始一直递增到10。
    而position正如前面所述,用于get或put 的操作,如果在往buffer里put完以后,不进行对position设置而直接get 的话,那自然是读取不了数据的。

    remaining()

    查询当前还有多少 “有效” 的数据可用,即判断position与limit 之间的差值。

    示例代码:

    循环 读取 控制台的输入内容,并写入到socket中

    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    while (true) {
       try {
               String s = reader.readLine();
               byte[] bytes = s.getBytes(utf8);
               buffer.clear();//每次写入buffer之前都清空一下
               buffer.put(bytes);
               buffer.flip();//每次准备从buffer里读取数据之前,都要重置一下position指针
               socketChannel.write(buffer);
           } catch (IOException e) {
               e.printStackTrace();
           }
    }
    

    为了初步了解,这段代码只是简单演示基本用法,实际上还要考虑bytes比buffer要大的情况,修改成如下代码:

    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    while (true) {
       try {
               String s = reader.readLine();
               byte[] bytes = s.getBytes(utf8);
               buffer.clear();
               for (int offset = 0; offset < bytes.length; offset++) {
                    buffer.put(bytes[offset]);
                    if (buffer.remaining() == 0) {
                         buffer.flip();
                         socketChannel.write(buffer);
                         buffer.clear();
                    }
               }
        } catch (IOException e) {
           e.printStackTrace();
        }
    }
    

    相关文章

      网友评论

          本文标题:JAVA NIO中的ByteBuffer

          本文链接:https://www.haomeiwen.com/subject/jneznxtx.html