用来定义缓冲区的所有类都以Buffer类为基类,Buffer定义了缓冲区的基本特征。

  直接子类:

  • ByteBuffer 用来存储byte类型的缓冲区,可以在这种缓冲区中存储任意其他基本类型的二进制值(boolean 除外)。存储的每个二进制值在缓冲区中占据的字节长度根据类型的长度决定,char和short占2个字节,int占4个字节;

  • CharBuffer 只存储char类型的值的缓冲区;

  • DoubleBuffer 只存储double类型的值的缓冲区;

  • FloatBuffer 只存储float类型的值的缓冲区;

  • IntBuffer 只存储int类型的值的缓冲区;

  • LongBuffer 只存储long类型的值的缓冲区;

  • ShortBuffer 只存储short类型的值的缓冲区。

  小结:没有boolean类型的缓冲区,boolean可以用int代替。

1、缓冲区容量

  缓冲区容量是指缓冲区所能包含的值的最大数目而不是字节数目(除非存储byte类型的元素,byte占一个字节)。缓冲区的容量一旦创建不能改变。通过调用capacity()方法返回缓冲区容量。

2、缓冲区的limit和position

3、创建缓冲区

  缓冲区类没有公共的构造函数,可以用静态工厂的方法创建。可以调用静态方法allocate()方法创建ByteBuffer缓冲区对象。

ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
IntBuffer intBuffer = IntBuffer.allocate(100);

  第一行创建一个容量为1024,position为0。

  第二行创建了一个容量为100,limit为100,占据了400个字节的(因为每个int4个字节),position为0的缓冲区。 

  实践得知除了ByteBuffer之外的缓冲区无法进行IO操作。通常创建ByteBuffer,在通过ByteBuffer创建其他的缓冲区。

a、创建视图缓冲区

  可以用ByteBuffer对象创建其他类型的缓冲区,新缓冲区共享原始ByteBuffer的全部或者部分内存,这样的缓冲区被叫做视图缓冲区。

  视图缓冲区有两种用途:

  • 在非byte类型的数据项被写入到文件中之前把他们加载到ByteBuffer中;
  • 在从文件中读取的数据作为非byte类型的数据的值进行访问。

  创建IntBuffer类型的视图缓冲区

ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
IntBuffer intBuffer = byteBuffer.asIntBuffer();

  intBuffer的最大容量为1024/4 (int为4个字节),position为0。

b、复制和切分缓冲区

  调用duplicate()方法复制缓冲区,这个方法返回和原始缓冲区一样类型的缓冲区,并且共享原始缓冲区的内存,但是容量和limit是单独分开的。

  调用slice()切分缓冲区,生成的缓冲区被映射到原始缓冲区的一部分,从location到limit-1。同样内存共享,但是容量和limit是单独分开的。

c、通过封装数组来创建缓冲区

  通过warp()方法来创建缓冲区。

String string = "young ken 的技术博客";
byte[] bytes = string.getBytes();
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);

  这里的bytes和缓冲区用的是一块内存,如果修改缓冲区的数据数组的数据也发生变化。

4、标记缓冲区

  通过mark()方法进行标记,如对缓冲区进行和一系列设置如

 ByteBuffer byteBuffer = ByteBuffer.allocate(100);
byteBuffer.limit(50);
byteBuffer.position(2);
byteBuffer.mark();

  现在对缓冲区进行了标记,标记的状态为limit50,position2。我现在要设置position为5,操作完之后调用reset(),缓冲区将重新变成limit50,position2。

5、缓冲区数据传输

  在将缓冲区的数据写入文件之前必须将数据加载到缓冲区。将数据加载到缓冲区的方法是put(),可以用get()方法取到数据。

  put和get有相对和绝对之分,如果是相对操作那么缓冲区的position会发生变化,如果是绝对position就是当前position。

a、传输数据到缓冲区

  • put(byte b)  将制定的byte存入到缓冲区中,position+1;
  • put(int index, byte b)  将byte传输到缓冲区指定索引位置。position不变;
  • put(byte[] array)  将array数组传输到缓冲区当前的position中,position+数组的长度;
  • put(byte[] array, int offset, int length)  将数组的array[offset]到array[length-1]添加到缓冲区中,position+数组的长度;
  • put(ByteBuffer src)  将src保留的字节传输到缓冲区中,包括缓冲区src中从当前索引位置limit-1位置的元素。

b、从缓冲区中提取数据

  • get() 从缓冲区中返回当前position的值,position+1;
  • get(int index) 返回索引index的字节;
  • get(byte[] bytes) 从缓冲区位置0开始,提取bytes.length长度的字节。position+bytes.length;
  • get(byte[] bytes, int offset, int length) 从当前缓冲区的position开始,提取length的字节从offset开始。position+length。

6、flip()和clear()

  • 现在我们要将数据写到输出通道中。在这之前,我们必须调用 flip() 方法。这个方法做两件非常重要的事,它将 limit 设置为当前 position,将 position 设置为 0;

  • clear() 方法。这个方法重设缓冲区以便接收更多的字节。 Clear 做两种非常重要的事情,它将 limit 设置为与 capacity 相同,它设置 position 为 0。

 作者   Young-Ken(微博)

                                                  审阅者 Cindy-Leee(微博)

转载请注明 http://www.cnblogs.com/youngKen/p/4923635.html

Java NIO流 -- 缓冲区(Buffer,ByteBuffer)的更多相关文章

  1. Java NIO之缓冲区Buffer

    Java NIO的核心部件: Buffer Channel Selector Buffer 是一个数组,但具有内部状态.如下4个索引: capacity:总容量 position:下一个要读取/写入的 ...

  2. Java NIO中的Buffer 详解

    Java NIO中的Buffer用于和NIO通道进行交互.如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的.缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这块内存被包装成NIO ...

  3. NIO之缓冲区(Buffer)的数据存取

    缓冲区(Buffer) 一个用于特定基本数据类行的容器.有java.nio包定义的,所有缓冲区都是抽象类Buffer的子类. Java NIO中的Buffer主要用于与NIO通道进行交互,数据是从通道 ...

  4. Java NIO Channel和Buffer

    Java NIO Channel和Buffer @author ixenos Channel和Buffer的关系 1.NIO速度的提高来自于所使用的结构更接近于OS执行I/O的方式:通道和缓冲器: 2 ...

  5. JAVA NIO缓冲区(Buffer)------ByteBuffer常用方法

    参考:https://blog.csdn.net/xialong_927/article/details/81044759 缓冲区(Buffer)就是在内存中预留指定大小的存储空间用来对输入/输出(I ...

  6. NIO流—理解Buffer、Channel概念和NIO的读写操作

    NIO流与IO流的区别 面向流与面向块 IO流是每次处理一个或多个字节,效率很慢(字符流处理的也是字节,只是对字节进行编码和解码处理). NIO流是以数据块为单位来处理,缓冲区就是用于读写的数据块.缓 ...

  7. Java NIO 之缓冲区

    缓冲区基础 所有的缓冲区都具有四个属性来 供关于其所包含的数据元素的信息. capacity(容量):缓冲区能够容纳数据的最大值,创建缓冲区后不能改变. limit(上界):缓冲区的第一个不能被读或写 ...

  8. Java NIO——2 缓冲区

    一.缓冲区基础 1.缓冲区并不是多线程安全的. 2.属性(容量.上界.位置.标记) capacity limit  第一个不能被读或写的元素 position  下一个要被读或写的元素索引 mark ...

  9. Java NIO4:缓冲区Buffer(续)

    一.什么是缓冲区      一个缓冲区对象是固定数量的数据的容器,其作用是一个存储器,或者分段运输区,在这里数据可被存储并在之后用于检索.缓冲区像前篇文章讨论的那样被写满和释放,对于每个非布尔原始数据 ...

随机推荐

  1. jQuery DataTables Plugin Meets C#

    Over the weekend, I was doing some work on the internal CMS we use over at eagleenvision.net and I w ...

  2. 关于.net中的脚本语言使用

    基于.net中drl框架的脚本现在有很多,最近也由于工作的需要,目前有lua.python.ruby.javascript的.net实现,对ruby不怎么了解,python.lua.js就成了试验的对 ...

  3. HDU4647+贪心

    /* 贪心. 题意:给定一些点 一些边 点和边都有价值.现在A B 选点.求A-B的maxVal 思路:分割边.边的1/2分给两个端点. 如果这两个点被同一个人取,则ok:否则 做减法也行,对题意无影 ...

  4. What is the innovator’s solution——什么才是创新的解决方案2

    前略:http://www.cnblogs.com/Kassadin/p/4233497.html 案例1 从书上的一个案例开始: 让我们来看看AT&T公司(美国电话电报公司)的案例吧.198 ...

  5. linux mysql数据库安装(tar.gz)

    概述 mysql数据库在linux下可以充分发挥威力,mysql数据库越来越受到软件公司的青睐,为什么呢? 免费.跨平台.轻.支持多并发 在北京很多软件公司属于创业型的中.小公司,从节约成本的角度考虑 ...

  6. 安卓从业者应该关注:Android 6.0的运行时权限

    Android 6.0,代号棉花糖,自发布伊始,其主要的特征运行时权限就很受关注.因为这一特征不仅改善了用户对于应用的使用体验,还使得应用开发者在实践开发中需要做出改变. 没有深入了解运行时权限的开发 ...

  7. Android:再按一次退出程序

    感觉这种效果比较友好 //两秒内按返回键两次退出程序 private long exitTime = 0; @Override public boolean onKeyDown(int keyCode ...

  8. 217. Contains Duplicate

    题目: Given an array of integers, find if the array contains any duplicates. Your function should retu ...

  9. POJ2418——Hardwood Species(map映射)

    Hardwood Species DescriptionHardwoods are the botanical group of trees that have broad leaves, produ ...

  10. Armitage主屏幕说明与命令行启动

    (1)我们将Armitage主屏幕标注为A.B和C A:该区域显示预配置的模块.您可以在模块列表下面的文本框中输入要查找的模块进行查找. B:该区域显示我们可以进行漏洞测试的活跃主机. C:该区域显示 ...