读书人

Java NIO读书笔记之Buffer缓冲区(2)

发布时间: 2012-12-28 10:29:04 作者: rapoo

Java NIO读书笔记之Buffer缓冲区(二)
11.创建缓冲区

创建缓冲区通常有两种方式:分配和包装

分配:CharBuffer charBuffer = CharBuffer.allocate(1000);

包装:
char[] array = new char[100];
CharBuffer charBuffer = CharBuffer.wrap(array);

public static void main(String[] args) {
char[] array = new char[100];
CharBuffer charBuffer = CharBuffer.wrap(array);
charBuffer.put('H').put('e').put('l').put('l').put('o');
for(char c : array){
if(c != '\0')
System.out.print(c);
} //Hello

array[1] = 'a';

charBuffer.flip();
for(int i = 0;i < charBuffer.limit(); i++){
System.out.print(charBuffer.get());
} //Hallo
}

通过wrap方法构建的缓冲区,改变数组的时候会改变缓冲区,改变缓冲区的时候数组同样会发生变化
wrap方法还提供了一个重载的版本:
wrap(txt, offset, length);
不过offset和length并不是取一个数组的子集,offset和length参数会初始化缓冲区的状态,position = offset, limit = offset +

length

通过allocate和wrap方法创建的缓冲区都可以获得备份数组,hasArray()可以得到缓冲区是否有一个可存取的备份数组,array()返回备份

数组的引用,如果hasArray()返回false,那么调用array()方法将会抛出UnsupportedOperationException

12.复制缓冲区

public abstract class CharBuffer
extends Buffer implements CharSequence, Comparable
{

public abstract CharBuffer duplicate();

public abstract CharBuffer asReadOnlyBuffer();

public abstract CharBuffer slice();
}

duplicate():
创建一个新的缓冲区,该缓冲区与原缓冲区共享数据元素,拥有同样的容量,每个缓冲区拥有各自的position、limit和mark属性,对一个

缓冲区数据的改变会映射到另一个缓冲区上,如果原缓冲区的属性为只读,那么新缓冲区的属性也是只读的。

public static void main(String[] args) {
CharBuffer charBuffer = CharBuffer.allocate(10);
charBuffer.put(new char[]{'H', 'e', 'l', 'l', 'o'});
CharBuffer charBuffer2 = charBuffer.duplicate();
System.out.println("Dup position:" + charBuffer2.position());
System.out.println("Dup limit:" + charBuffer2.limit());
System.out.println("Dup capacity:" + charBuffer2.capacity());
charBuffer2.flip();
System.out.println("Old position:" + charBuffer.position());
System.out.println("Old limit:" + charBuffer.limit());
System.out.println("Old capacity:" + charBuffer.capacity());
charBuffer2.position(2);
charBuffer2.compact();
charBuffer.flip();
for(int i = 0; i < charBuffer.limit(); i++){
System.out.print(charBuffer.get()); //llolo
}
}

asReadOnlyBuffer():
通过此方法创建一个只读的缓冲区,这个新缓冲区不允许使用put()来进行操作。

slice():
创建一个从原缓冲区当前位置开始的新缓冲区,其容量是(limit - position)这个新缓冲区与原始缓冲区共享一段数据元素子序列,分割出

来的序列也会只继承可读属性。

13.直接缓冲区:
直接缓冲区被用于与通道和固有IO例程的交互,它们通过使用固有代码来告知操作系统直接释放或填充内存区域。只有ByteBuffer类型的缓

冲区才能够被创建为直接缓冲区类型:
ByteBuffer byteBuffer = ByteBuffer.allocateDirect();
另外所有的缓冲区都提供了一个isDirect()的方法来判断该缓冲区是否是直接缓冲区。

public static void main(String[] args){
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
System.out.println(byteBuffer.isDirect()); //false
byteBuffer = ByteBuffer.allocateDirect(10);
System.out.println(byteBuffer.isDirect()); //true
}

14.视图缓冲区:

视图缓冲区通过已存在的缓冲区对象实例的工厂方法来创建,这种视图对象维护它自己的属性,容量,位置,上界和标记。但是和原来的缓冲区共享数据。

public abstract class ByteBuffer
extends Buffer implements Comparable{

public abstract CharBuffer asCharBuffer();

public abstract ShortBuffer asShortBuffer();

public abstract IntBuffer asIntBuffer();

public abstract LongBuffer asLongBuffer();

public abstract FloatBuffer asFloatBuffer();

public abstract DoubleBuffer asDoubleBuffer();

}

15.数据元素视图:

ByteBuffer采取了一种轻量机制,可以将字节组合为多字节的数据类型来存取

ByteBuffer byteBuffer = ByteBuffer.allocate(10);
int value = byteBuffer.getInt(); //取得整形值

getInt方法将会取当前position开始的4个字节,并将其包装成int

读书人网 >编程

热点推荐