Java NIO(一) Buffer类源码分析
Buffer类是一个抽象类。它是ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer 和 ShortBuffer的基类。
- Buffer类的四个属性
private int mark = -1;// 一个备忘的位置,即保存着上一次position的位置信息。
private int position = 0;//下一个要被读或写的元素的索引
private int limit;//缓冲区的第一个不能被读或写的元素。
private int capacity; // Buffer的容量,即缓冲区能够缓存数据元素的最大数量
- Buffer类的构造函数
// 初始化四个属性的值,由于buffer类是抽象类,外部无法对其初始化,它的初始化方法由其子类来调用。
Buffer(int mark, int pos, int lim, int cap) { // package-private
if (cap < 0)
throw new IllegalArgumentException("Negative capacity: " + cap);
this.capacity = cap; // 设置缓冲区的大小
limit(lim);// 设置读写的上界
position(pos); // 设置当前读的位置
if (mark >= 0) {
if (mark > pos)
throw new IllegalArgumentException("mark > position: ("
+ mark + " > " + pos + ")");
this.mark = mark;// 设置上次读写的位置
}
}
// 保证limit的值不大于capacity,不小于0,并且保证position的值不大于limit
public final Buffer limit(int newLimit) {
if ((newLimit > capacity) || (newLimit < 0))
throw new IllegalArgumentException();
limit = newLimit;
if (position > limit) position = limit;
if (mark > limit) mark = -1;
return this;
}
// 保证position不大于limit,不小于0,同时不小于mark的值
public final Buffer position(int newPosition) {
if ((newPosition > limit) || (newPosition < 0))
throw new IllegalArgumentException();
position = newPosition;
if (mark > position) mark = -1;
return this;
}
- Buffer类的常用方法
// 将position设置为0,limit保持不变,意味着你可以重读缓冲区的值.
public final Buffer rewind() {
position = 0;
mark = -1;
return this;
}
// flip方法将Buffer从写模式切换到读模式。调用flip()方法会将position设回0,并将limit设置成之前position的值。换句话说,position现在用于标记读的位置,limit表示之前写进了多少个byte、char等,从写模式切换到读模式必须调用该方法。
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
// 标记上次读写的位置,可用于回退
public final Buffer mark() {
mark = position;
return this;
}
// position将被设回0,limit被设置成 capacity的值。换句话说,Buffer 被清空了。Buffer中的数据并未清除,只是这些标记告诉我们可以从哪里开始往Buffer里写数据。limit设置为capacity后,我们无法知道读数据从哪里结束
public final Buffer clear() {
position = 0;
limit = capacity;
mark = -1;
return this;
}
// 将position设置为mark,意味着可以恢复到操作之前的状态
public final Buffer reset() {
int m = mark;
if (m < 0)
throw new InvalidMarkException();
position = m;
return this;
}