Buffer
缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象,并提供了一组方法,用来方便的访问该块内存。
- capacity(容量)
- position(位置)
- limit(上限)
capacity
capacity代表着Buffer的固定大小值,能存放的最大值不超过capacity。
position
- 当写数据到Buffer中时,position表示当前的位置。
- 当读取数据时,也是从某个特定位置读。
- 当将Buffer从写模式切换到读模式,position会被重置为0。
- 当从Buffer的position处读取数据时,position向前移动到下一个可读的位置。
limit
- 在写模式下,Buffer的limit表示你最多能往Buffer里写多少数据。写模式下,limit等于Buffer的capacity。
- 当切换Buffer到读模式时, limit表示你最多能读到多少数据。
- 当切换Buffer到读模式时,limit会被设置成写模式下的position值。
- 也就是说,可以能读到之前写入的所有数据(limit被设置成已写数据的数量,这个值在写模式下就是position)
mark
- 标记,调用mark()来设置mark=position。
- 调用reset()可以让position恢复到标记的位置即position=mark。
Buffer关键源码
public abstract class Buffer {
private int mark = -1;
private int position = 0;
private int limit;
private int capacity;
//构造方法
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;
}
}
public final Buffer position(int newPosition) {
if ((newPosition > limit) || (newPosition < 0))
throw new IllegalArgumentException();
position = newPosition;
if (mark > position) mark = -1;
return this;
}
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;
}
public final Buffer mark() {
mark = position;
return this;
}
public final Buffer reset() {
int m = mark;
if (m < 0)
throw new InvalidMarkException();
position = m;
return this;
}
public final Buffer clear() {
position = 0;
limit = capacity;
mark = -1;
return this;
}
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
public final Buffer rewind() {
position = 0;
mark = -1;
return this;
}
public final int remaining() {
return limit - position;
}
public final boolean hasRemaining() {
return position < limit;
}
final void truncate() { // package-private
mark = -1;
position = 0;
limit = 0;
capacity = 0;
}
final void discardMark() { // package-private
mark = -1;
}
}