用来定义缓冲区的所有类都以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. [转载]mongoDB学习笔记——存取图片(C#)

    作为一个NoSql数据库的代表,存取多媒体数据,应该是强项吧?那么,图片在mongoDB里是如何存取的呢?(其实,关系型数据库存取图片也一点问题没有,所以我看NoSql的强项不在于是否存储多媒体,而在 ...

  2. DataGridView 列自适应宽度 设置

    代码: Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; 或者设置DataGridView的AutoSizeColu ...

  3. PE 文件

    一.PE文件基本结构 上图便是PE文件的基本结构.(注意:DOS MZ Header和部分PE header的大小是不变的:DOS stub部分的大小是可变的.) 二.Section 详解 一个PE文 ...

  4. 线程以及数据对象的wait()和notifyAll()方法

    正在运行的程序称作一个进程,一个进程可以包含多个线程,这些线程可以共享进程的资源,它们共用一块存储空间.那么,各个线程在访问同一个数据对象的同时,可能引起冲突,以生产者.消费者为例,就会出现队列中没有 ...

  5. 如何定位Release 版本中程序崩溃的位置 ---利用map文件 拦截windows崩溃函数

    1       案例描述 作为Windows程序员,平时最担心见到的事情可能就是程序发生了崩溃(异常),这时Windows会提示该程序执行了非法操作,即将关闭.请与您的供应商联系.呵呵,这句微软的“名 ...

  6. POJ3207+tarjan+2-sat

    /* 2-sat 题意:给定一个圆,圆上一些点.两点一线.现给出一些线,这些线可以在圆内连起来,也可以在圆外. 问有没有可能所有的线画完 且 不出现相交. 思路:把线画在圆内或圆外 看成一个组合.其它 ...

  7. PowerDesigner(五)-概念数据模型(CDM生成LDM,PDM和OOM)

    概念数据模型 概念数据模型(Conceptual Data Model,CDM):表达的是数据整体逻辑结构,该结构独立于任何软件和数据存储结构,即它只是系统分析人员,应用程序设计人员,维护人员和用户之 ...

  8. codeforces #310 div1 B

    我们考虑n-1座桥每座桥需要的长度在一个区间[L,R]中 之后我们现在有m座桥,每个桥的长度为k 题意就是要求一个匹配方案 显然如果数据范围不大直接KM就可以了 可是20w的数据KM显然要T 所以我们 ...

  9. __init和__exit宏的作用

    原文地址:http://blog.csdn.net/zhenwenxian/article/details/8564574 内核的部分函数带有__init和__exit宏,负责“初始化”和“清理收尾” ...

  10. arcgis 10.2 安装教程

    arcgis 10.2 安装教程(含下载地址)_百度经验 http://jingyan.baidu.com/article/fc07f98911b66912ffe5199b.html arcgis 1 ...