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方法的原因。

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

相关文章推荐

Java中substring内存泄露问题

在Java中,String是最常用的数据类型,String有一个substring方法用来截取字符串,或许我们没注意到该方法可能会引起内存泄露问题(出现于Java6中)。 方法介绍: 在Jav...

Maven构建Spring Boot+Mybatis+derby的配置

最近项目用到了spring boot和derby的内嵌模式组合,感觉derby作为内嵌数据库的话,使用极其小巧方便,不需要再去配置什么server了,所以整理了一下,写了个简短的demo,因为习惯用m...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

netty学习十一:NIO客户端服务端通讯demo

netty学习十一:NIO客户端服务端通讯demo

支持wmv、mpg、mov、avi格式的网页视频播放代码

这2天一直在整金网奖的相关项目,比较头大的就是网页视频播放了,需要考虑各种不同格式的视频,然后找相应的视频播放器。这次使用了2种方法对这些视频进行处理:1、使用ckplayer网页视频播放器ckpla...

高性能Web架构

来源:彗星计划 引言 最新中国互联网络信息中心(CNNIC)发布的《第38次中国互联网络发展状况统计报告》,2016年6月,我国网民规模达7.1亿。全球互联网网站数量超过10亿个。如此多的...

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
  • 368

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

一.基本概念 IO 是主存和外部设备 ( 硬盘、终端和网络等 ) 拷贝数据的过程。 IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成。 所有语言运行时系统提供执行 I/O 较高级别...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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