Java-NIO(2)
缓冲区
常规I/O操作存在很大缺点,主要是因为它们是阻塞的,而NIO正是为了解决常规I/O执行效率低的问题,采用非阻塞高性能运行的方式来避免出现笨拙的同步I/O带来的效率低的问题
缓冲区Buffer,在NIO的使用中地位很高,因为数据就是放到缓冲区,对数据进行处理的
NIO中的Buffer是一个用于存储基本数据类型的容器,它以类似于数组有序的方式来存储和组织数据,每个基本数据类型(除boolean)都有一个子类相对应
Buffer类
Buffer类及其子类都是抽象类,不能直接实例化,使用方式是将对应的数据类型的数组包装进入缓冲区,借助静态方法wrap实现
API
NIO缓冲区中,有四个重要的参数:
-
capacity-容量
-
limit-限制
-
position-位置
-
mark-标记
四个之间的大小关系
0 <= mark <= position <= limit <= capacity
capacity
代码包含元素的数量。值不能为负数,且不可更改
方法:
/**
* Returns this buffer's capacity.
*
* @return The capacity of this buffer
*/
public final int capacity() {
return capacity;
}
public class T1 {
public static void main(String[] args) {
byte[] bytes = new byte[]{1,2,3};
short[] shorts = new short[]{1,2,3,4};
int[] ints = new int[]{1,2,3,4,5};
long[] longs = new long[]{1,2,3,4,5,6};
float[] floats = new float[]{1,2,3,4,5,6,7};
double[] doubles = new double[]{1,2,3,4,5,6,7,8};
char[] chars = new char[]{'a','b','c','d','e'};
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
ShortBuffer shortBuffer = ShortBuffer.wrap(shorts);
IntBuffer intBuffer = IntBuffer.wrap(ints);
LongBuffer longBuffer = LongBuffer.wrap(longs);
FloatBuffer floatBuffer = FloatBuffer.wrap(floats);
DoubleBuffer doubleBuffer = DoubleBuffer.wrap(doubles);
CharBuffer charBuffer = CharBuffer.wrap(chars);
print(byteBuffer);
print(shortBuffer);
print(intBuffer);
print(longBuffer);
print(floatBuffer);
print(doubleBuffer);
print(charBuffer);
}
private static void print(Buffer buffer) {
System.out.println("Name : \n");
System.out.println(buffer.getClass().getName() + "\n");
System.out.println("Capacity : \n");
System.out.println(buffer.capacity());
System.out.println("----------------------------------");
}
}
看下ByteBuffer中wrap方法:
//将字节数组包装到缓冲区中。
//新缓冲区将由给定的字节数组支持; 也就是说,对缓冲区的修改将导致数组被修改,反之亦然。 新缓冲区的容量和限制将为array.length,其位置为零,其标记为未定义,其字节顺序为BIG_ENDIAN。 它的支持数组将是给定的数组,其数组偏移量将为零。
public static ByteBuffer wrap(byte[] array) {
return wrap(array, 0, array.length);
}
limit
何为限制?缓冲区的限制代表了第一个不应该读取或者写入元素的index(索引),limit不可以为负,且不可以大于capacity,假设position大于limit,那么将position设置为新的limit,假设mark已定义且大于新的limit,则丢弃mark
limit应用图示:
测试:
public class T2 {
public static void main(String[] args) {
char[] chars = new char[]{'a','b','c','d','e'};
CharBuffer charBuffer = CharBuffer.wrap(chars);
System.out.println("capacity : \n");
System.out.println(charBuffer.capacity());
System.out.println("");
System.out.println("Limit : \n");
System.out.println(charBuffer.limit());
S