netty学习十二:了解NIO Buffer中的postion和capacity和limit

原创 2017年08月22日 06:27:16

概述


  • postion
  • capacity
  • limit

这三个属性是Buffer对象的关键属性,要理解NIO中的Buffer,必须先理解这三个属性,本文会使用一些简单例子来逐步说明三个属性的含义。

下文的所有demo都是使用IntBuffer来做演示的

理解capacity


 public static void main(String[] args){
        IntBuffer intBuffer = IntBuffer.allocate(5);
        System.out.println("capacity:"+intBuffer.capacity());
 }

当创建一个固定容量的IntBuffer后,capacity的内容如下

capacity:5

Buffer对象是一个容器(底层用数组实现),里面可以存储JAVA基本类型数据,像int、byte、long等。
其中Buffer对象的capacity属性表示容器的容量,这个是不能变的。通过

IntBuffer.allocate(5)

创建一个capacity=5的IntBuffer对象,这个IntBuffer对象只能存储5个数字。

public static void main(String[] args){
        IntBuffer intBuffer = IntBuffer.allocate(0);
        System.out.println("capacity:"+intBuffer.capacity());

        intBuffer.put(1);
        intBuffer.put(2);
        intBuffer.put(3);
        intBuffer.put(4);
        intBuffer.put(5);
        intBuffer.put(6);
}

如果试图为IntBuffer添加第6个数字,将会抛出

java.nio.BufferOverflowException


理解position


概念

下一个要被读或写的元素的位置,当调用相应的get( )和put( )方法,postion会被修改。

public static void main(String[] args){
        IntBuffer intBuffer = IntBuffer.allocate(5);
        System.out.println("position:"+intBuffer.position());
}

当刚创建一个Buffer对象时,还未进行put和get操作,postion的初始值为0。
执行上面的代码,输出如下

position:0

当往Buffer对象中put元素的时候,postion随着移动。

public static void main(String[] args){
        IntBuffer intBuffer = IntBuffer.allocate(5);
        intBuffer.put(1);
        intBuffer.put(2);
        System.out.println("position:"+intBuffer.position());
}

运行代码,执行结果如下

position:2

这里的2表示,put下一个元素的时候,可以在2这个位置上插入数据。要移动Buffer对象中postion的位置,
另外一个办法是使用get()方法,每调用一次,postion增加1。

 public static void main(String[] args){
        IntBuffer intBuffer = IntBuffer.allocate(5);
        intBuffer.put(1);
        intBuffer.put(2);
        System.out.println("position:"+intBuffer.position());
        System.out.println("=======================");

        System.out.println(intBuffer.get());
        System.out.println("position:"+intBuffer.position());
        System.out.println("=======================");

        System.out.println(intBuffer.get());
        System.out.println("position:"+intBuffer.position());
        System.out.println("=======================");

        System.out.println(intBuffer.get());
        System.out.println("position:"+intBuffer.position());
        System.out.println("=======================");
}

上面的代码输出如下

position:2
=======================
0
position:3
=======================
0
position:4
=======================
0
position:5
=======================

总共调用了3次get方法,但是3次get方法的返回值都是0。当多调用一次get()方法的时候,将会抛出

java.nio.BufferUnderflowException

原因是positon已经超过capacity了。

那么如何获取Buffer对象中的元素呢?可以使用get(index)方法,读取元素的时候,指定索引。
备注

get(index)方法是不会改变postion位置的。

 public static void main(String[] args){
        IntBuffer intBuffer = IntBuffer.allocate(5);
        intBuffer.put(1);
        intBuffer.put(2);

        System.out.println(intBuffer.get(0));
        System.out.println("postion:"+intBuffer.position());
        System.out.println("================");
        System.out.println(intBuffer.get(1));
        System.out.println("postion:"+intBuffer.position());
}

输出结果如下

1
postion:2
================
2
postion:2

如果想替换某个index上的值,可以使用

put(int index, int i)

 public static void main(String[] args){
        IntBuffer intBuffer = IntBuffer.allocate(5);
        intBuffer.put(1);
        intBuffer.put(2);

        System.out.println(intBuffer.get(0));
        System.out.println("postion:"+intBuffer.position());
        System.out.println("================");
        System.out.println(intBuffer.get(1));
        System.out.println("postion:"+intBuffer.position());

        System.out.println("================");
        intBuffer.put(0,3);
        System.out.println(intBuffer.get(0));
}

执行结果如下

1
postion:2
================
2
postion:2
================
3

0这个index上的值已经从1改成3了。


理解limit


得从两个角度来理解limit。

  • 当往Buffer对象里put数据的时候,limit一直都是等于capacity,表示最多能往Buffer对象里写多少数据
  • 当调用Buffer对象的flip()方法后,想从Buffer对象读取数据时,position被设置为0,limit被设置为之前的postion,这个时候的limit表示最多能从Buffer读取多少数据。换句话说,你能读到之前写入的所有数据。
 public static void main(String[] args){
        IntBuffer intBuffer = IntBuffer.allocate(5);
        intBuffer.put(1);
        intBuffer.put(2);
        System.out.println("limit:"+intBuffer.limit());
        System.out.println("postion:"+intBuffer.position());

        intBuffer.flip();
        System.out.println("调用flip方法后");
        System.out.println("postion:"+intBuffer.position());
        System.out.println("limit:"+intBuffer.limit());
  }

输出结果如下

limit:5
postion:2
调用flip方法后
postion:0
limit:2

当往Buffer对象里写入数据后,接着想从Buffer对象读取数据时,程序如何知道最多能从Buffer对象里读取多少数据呢?这正是limit属性被引入的目的。也是读取数据时,为什么要先调用filp方法的原因。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

sun.misc.BASE64Decoder报错

项目中引用import sun.misc.BASE64Decoder;的时候报错,说找不到BASE64Decoder  解决办法下:  1. Open project properties.  ...

Java 3DES加密 javax.crypto.IllegalBlockSizeException: data not block size aligned

javax.crypto.IllegalBlockSizeException: data not block size aligned

Java NIO通俗编程之缓冲区内部细节状态变量position,limit,capacity(二)

一、介绍 我们介绍了NIO中的两个核心对象:缓冲区和通道,在谈到缓冲区时,我们说缓冲区对象本质上是一个数组,但它其实是一个特殊的数组,缓冲区对象内置了一些机制,能够跟踪和记录缓冲区的状态变化情况,如果...
  • pfnie
  • pfnie
  • 2016年10月16日 12:01
  • 738

Java NIO框架Netty教程(十二) 并发访问测试(中)

写在前面:对Netty并发问题的测试和解决完全超出了我的预期,想说的东西越来越多。所以才出现这个中篇,也就是说,一定会有下篇。至于问题点的发现,OneCoder也在努力验证中。 继续并发的问题。...

Java NIO 中的Buffer和Channel了解

Java NIO包中的SocketChannel和Selector。Java NIO

NIO学习笔记之缓冲区Buffer

缓冲区的基类:BufferBuffer有四个属性: 1、capacit(容量) 2、limit(上界) 3、position(位置) 4、mark(标记)*:绝对存储不会影响缓冲区的位置属性存...

TCP-IP学习笔记二:NIO的网络编程Buffer简单使用

TCP/IP学习笔记二:NIO的网络编程Buffer简单使用标签(空格分隔):网络编程 NIO BufferNIO的有三种模型:ByteBuffer (position/limit/capacity)...
  • MOTUI
  • MOTUI
  • 2016年10月11日 21:35
  • 452

Java nio 学习笔记(一) Buffer(缓冲区)与Channel(通道)的相关知识

一.基本概念 IO 是主存和外部设备 ( 硬盘、终端和网络等 ) 拷贝数据的过程。 IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成。 所有语言运行时系统提供执行 I/O 较高级别...

Java NIO 学习(二)--Buffer

在第一节中,简单的描述了NIO三个核心的类:channel、buffer、selector;由于缓冲区作为操作的基本,而且底层channel接口没有过多细节(只有两个方法:isOpen、close)这...

java nio 学习之 Buffer 类

之前听别人说java nio,以为是封装的多线程处理io,提高并发能力,支持批量下载,今天了解才发现是java new io. 主要包括3个核心 : buffer(走缓冲),selector(选择器...
  • xubo_ob
  • xubo_ob
  • 2016年08月23日 16:38
  • 170
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:netty学习十二:了解NIO Buffer中的postion和capacity和limit
举报原因:
原因补充:

(最多只允许输入30个字)