Java nio是jdk1.4增加的新的IO,Nio比起字节、字符流用起来更简洁,效率更高。和nio相关的JDK主要是java.nio和java.nio.x。
Buffer是nio的核心类之一,顾名思义就是缓冲区,它是一个抽象类,用来存储数据或作为数据的中转站。Buffer的子类主要有一下7个:
- ByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
但是一般只有ByteBuffer和CharBuffer是常用。
ByteBuffer类主要属性:
- mark:缓冲区的位置标记。
- position:缓冲区的位置
- limit:缓冲区的限制
- capacity:缓冲区的容量
- isReadOnly:只读标记
- nativeByteOrder:排序标记
- offset:偏移量
下面是Buffer的构造函数,
Buffer(int paramInt1, int paramInt2, int paramInt3, int paramInt4) {
if (paramInt4 < 0)
throw new IllegalArgumentException("Negative capacity: " + paramInt4);
this.capacity = paramInt4;
limit(paramInt3);
position(paramInt2);
if (paramInt1 < 0)
return;
if (paramInt1 > paramInt2)
throw new IllegalArgumentException("mark > position: (" + paramInt1 + " > " + paramInt2 + ")");
this.mark = paramInt1;
}
我们能从中得到前四个属性的关系:
0<=mark<=position<=limit<=capacity,
一旦这四个属性不符合这个关系,你的代码就会抛出IllegalArgumentException。
除了上面属性的getter和setter方法ByteBuffer的主要方法:
- get(int index) 和 getX (X代表java的包装类型) :获取缓冲区中的内容。
- put(byte b) 和 putX : 将数据存入缓冲区。
- slice() :创建新的字节缓冲区,其内容是此缓冲区内容的共享子序列。
- wrap(byte[] array) :将 byte 数组包装到缓冲区中。
- clear() 使缓冲区为一系列新的通道读取或相对放置 操作做好准备:它将限制设置为容量大小,将位置设置为 0。
- flip() 使缓冲区为一系列新的通道写入或相对获取 操作做好准备:它将限制设置为当前位置,然后将位置设置为 0。
- rewind() 使缓冲区为重新读取已包含的数据做好准备:它使限制保持不变,将位置设置为 0。
clear的源代码:
public final Buffer clear() {
this.position = 0;
this.limit = this.capacity;
this.mark = -1;
return this;
}
如果你的缓冲区位置关系当时是这样的:
当你使用clear后将会变成这样:
很容易理解吧,所以在你读取数据前最好clear下你的缓冲区,以便给出足够的空间存储数据。
flip()的源码
public final Buffer flip() {
this.limit = this.position;
this.position = 0;
this.mark = -1;
return this;
}
如果你的缓冲区位置关系当时是这样的:
当你使用flip后将会变成这样:
在写入数据前filp()下你的缓冲区能有效的写入数据,这是非常有必要的。
下面是一个使用ByteBuffer的测试例子:
ByteBuffer byteBuffer = ByteBuffer.allocate(127);
System.out.println("position value:"+byteBuffer.position());
System.out.println("limit value:"+byteBuffer.limit());
System.out.println("capacity value:"+byteBuffer.capacity());
for (int i = 0; i < byteBuffer.capacity(); i++) {
byteBuffer.put((byte)i);
}
System.out.println("position value:"+byteBuffer.position());
System.out.println("limit value:"+byteBuffer.limit());
System.out.println("capacity value:"+byteBuffer.capacity());
for (int i = 0; i < byteBuffer.capacity(); i++) {
System.out.println(byteBuffer.get(i));
}
然后下面是一部分输出结果:
*position value:0
limit value:127
capacity value:127
position value:127
limit value:127
capacity value:127
0
1
*
byteBuffer.flip();
使用flip()之后的输出结果:
*after flip buffer —-
position value:0
limit value:127
capacity value:127*
clear就交给大家自己去测试了,相信你会有所收获的!
buffer的字节还可以根据ByteOrder中BIG_ENDIAN
和LITTLE_ENDIAN 常量进行排序,这种排序讲起来还是比较复杂的,想了解的请自行查阅相关资料。
以上纯属个人对Buffer的理解,如有纰漏,望留言指正或发送到邮箱381763563@qq.com