第二章 缓冲区(9)
来源:互联网 发布:斗鱼抽奖 知乎 编辑:程序博客网 时间:2024/05/18 00:07
2.2 创建buffer对象
就像我们在图2.1中看到的那样,NIO中存在7种buffer的基本类型,对应于java中除了boolean的所有java基本数据类型(第八种buffer类型是MappedByteBuffer,它是ByteBuffer处理内存映射文件的特殊形式,我们将在第三章中讨论内存映射文件)。这些类型都是不能直接实例化的。它们都是抽象类,但是他们都有静态的工厂类来创建各种类型的对象。
对于下面的讨论,我们将使用CharBuffer作为例子,当然它也适用于其他的六种buffer类型:IntBuffer、DoubleBuffer、ShortBuffer、LongBuffer、FloatBuffer和ByteBuffer。下面是创建CharBuffer对象的主要方法,只要替代为名字就跟其他buffer类型一样。
public abstract class CharBuffer
extends Buffer implements CharSequence,Comparable{
public static CharBuffer allocate(int capacity);
public static CharBuffer wrap(char[] array);
public static CharBuffer wrap(char[] array,int offset,int length);
public final boolean hasArray();
public final char[] array();
public final int arrayOffset();
}
可以通过allocate方法和wrap方法来创建新的buffer对象。Allocate方法创建一个buffer对象,开辟capacity个元素的私有空间。Wrap方法会创建一个buffer对象,但是不会开辟任何数据空间。它将使用你提供的数组作为后备空间来保存数据。
为了开辟100个空间的CharBuffer对象,可以使用下面的代码:
CharBuffer charBuffer=CharBuffer.allocate(100);
它将暗中从堆中分配100个单元作为对象的后备空间来存储100个字符。
如果你想提供自己的数组来作为CharBuffer的后备空间,可以使用wrap方法来实现:
char[] myArray=new char[100];
CharBuffer charBuffer=CharBuffer.wrap(myArray);
这些代码将产生一个新的CharBuffer对象,但是数据将会保存在你提供的数组中。这也意味着你对CharBuffer对象做像put方法的更改将直接反应在你的数组上,你对数组的任何更改也会反映在CharBuffer对象上。使用offset和length参数版本的wrap方法将会创建一个根据你的参数设定的position和limit的buffer对象。下面的代码:
CharBuffer charBuffer=CharBuffer.wrap(myArray,12,24);
将会创建一个position=12、limit=24、capacity=myArray.length的CharBuffer对象。这个方法并不会像你想象的那样只占用你提供数组的一部分。Buffer对象将使用数组的全部空间;offset和limit参数只会设置CharBuffer的初始值。向这个buffer对象调用clear方法,然后填充数据直到buffer的position到达limit,就会使数组的数据被全部覆盖。2.3小节中将讨论slice方法产生一个只影响一部分数据的buffer对象。
通过allocate方法和wrap方法创建的Buffer对象都不是内核中的数据缓冲区,这些方法创建的缓冲区都存在后备数组,因而我们能够通过上面列出的API获取对这些数组的访问权。返回boolean值的hasArray方法可以返回这个buffer对象是否拥有后备数组,如果hasArray返回true,你就能从array方法得到buffer对象的后备数组引用。
如果hasArray方法返回false,你就不能使用array或者arrayOffset方法,否则你将得到一个UnsupportedOperationException异常。如果一个buffer对象是只读的,它的后备数组也是禁止访问的,尽管这个对象是通过wrap方法生成的。对只读buffer对象调用array或者arrayOffset方法将导致ReadOnlyException异常的抛出,当然这样是为了保证你不对只读的buffer对象进行访问或者修改。如果你拥有其他的方式来获得buffer对象的后备数组引用,你对数组的修改将会反映到只读的buffer对象上。关于只读buffer对象将在2.3节中进行详细的讨论。
到目前为止,这节讨论的内容适用于所有的其他buffer类型。但是我们作为例子的CharBuffer类型还提供了一个其他buffer类型不具备的方便使用的方法。
public abstract class CharBuffer
extends Buffer implements CharSequence,Comparable{
public static CharBuffer wrap(CharSequence csq);
public static CharBuffer wrap(CharSequence csq,int start,int end);
}
上面这些wrap方法创建了一些只读buffer类型的视图,得到的buffer对象的后备数组是CharSequence对象或者是CharSequence对象的子集(在第五章中我们对CharSequence对象进行详细的讨论)。CharSequence类描述了一系列可读取的字符串序列。在JDK1.4版本中,三个标准类实现了CharSequence接口:String、StringBuffer和CharBuffer。这个版本的wrap方法对于缓冲已经存在的字符串数据,然后使用Buffer的API来访问非常方便。这样做对于字符集处理(见第六章)和正则表达式处理(见第五章)非常便利。
CharBuffer charBuffer=CharBuffer.wrap("Hello World");
带三个参数形式的wrap方法,将索引从start到end的CharSequence传递给CharBuffer。它跟CharSequence.subsequence()方法一样方便。Start参数表示字符串序列的第一个字符,end参数表示最后一个字符加上一的位置。
- 第二章 缓冲区(9)
- 第二章 缓冲区(1)
- 第二章 缓冲区(2)
- 第二章 缓冲区(4)
- 第二章 缓冲区(5)
- 第二章 缓冲区(6)
- 第二章 缓冲区(7)
- 第二章 缓冲区(8)
- 第二章 缓冲区(10)
- 第二章 缓冲区(11)
- 第二章 缓冲区(12)
- 第二章 缓冲区(13)
- 读书笔记-《Java NIO》:第二章 缓冲区(1)
- 读书笔记-《Java NIO》:第二章 缓冲区(2)
- 第三章 缓冲区(3)
- 【第二弹】OpenGL深入学习之缓冲区
- Socket 字节缓冲区第二种方式
- Socket 字节缓冲区第二种方式
- .NET 部署-03Web Deployment项目-03配置管理
- [MySQL优化] -- 如何查找SQL效率地下的原因
- C#笔记一
- 一个非常好用的图片等比例缩放到指定最大高宽的函数
- [MySQL优化] -- 如何定位效率较低的SQL
- 第二章 缓冲区(9)
- 多线程编程(9) - 认识等待函数 WaitForSingleObject
- Google搜索指令大全(最新整理)
- 游戏编程知识摘录
- winform在打包程序中加入注册控件
- 很久未来,mark
- 教学课件——二次函数图象及性质
- 提高C#编程水平的50个要点
- 看了老男孩,回忆重重,你当年的梦想是什么?......实现了吗?