Buffer是一块内存,主要用在NIO Channel,比如FileChannel,SocketChannel。
对Channel的读写都是直接操作Buffer对象。
Buffer是一个工具类,提供了操作这个内存块的方法。
Buffer的实现主要有以下几种:
Buffer的类型:
- ByteBuffer
- MappedByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
Buffer基本使用
四步搞定
- 写数据到Buffer中
- 调用buffer.flip()
- 从buffer中读取数据
- 调用buffer.clear()或者buffer.compact()
buffer主要有四个主要属性:
- capacity: Buffer最大容量
- position:读写偏移
- limit:最大可读容量
- mark: 标记,可以调用reset重读或重写
只要理解了这四个属性,基本就掌握了Buffer的使用和原理。
我们来看下这三个属性的说明:
position和limit依赖于Buffer处于读模式还是写模式,capacity的意义在读模式和写模式都是一样的
- 1 capacity:Buffer的最大容量
- 2 position位置:写模式下:初始值为0,比如当你put(),putXXX()时,position累加,position最大值是capacity-1
读模式下:调用Buffer.flip从写模式切换到读模式,position被重置为0,其他与写模式的偏移累加一致
- 3 limit:写模式下:limit的值与capacity一致
读模式下:limit用来标志你能够读取多少数据,意思就是你只能读取写入的position数据。
- 4 mark:重置读写偏移
读写可以参考下图:

写模式下,posistion累加,limit和capacity不变,即可以写入的最大字数。
每次调用一次put()或者putXXXX()时,position+n(n为你写入的字数,如果写入一个字,则position+1,如果你写入字数组,position+数组.长度)
读模式:当调用flip()时,将limit设置为position,position设置为0,mark设置为-1,limit为能够读取的最大字数。
每调用一次get或者getXXX()时,position+n(n为你读取的字数,如果读取一个字,则position+1,如果你读取字数组,position+数组.长度)
Capacity在读模式和写模式下都不变。
Buffer.clear()和Buffer.compact()
读取完数据后,如果想要Buffer能够再次写入,可以调用clear和compact函数。
如果调用clear函数,position设置为0.limit设置为capacity,其实里面的数据并没有被清除,只是覆盖写。
但是有一个场景是,数据没有读取完成之前,你需要要先写入一些数据时,可以调用compact函数,这个函数会把没有读取完的数据拷贝到Buffer开始处,然后把position设置为n(n为未读取数据的长度),limit设置为capacity。
下面是一个简单的Demo:
// 基本使用
// 新建一个缓冲区,可以存放10个整数
IntBuffer intBuffer = IntBuffer.allocate(10);
// 没有元素的时候,注意:get的内容int为0,你有可能put 0,所以可以判断一下position
// 调用intBuffer.position()
// 否则get 会让position+1
System.out.println("current position should be 0, actually: " + intBuffer.position());
if (intBuffer.position() > 0) {
int empty_get = intBuffer.get();
}
// 连续放入10个元素
intBuffer.put(1);
intBuffer.put(2);
intBuffer.put(3);
intBuffer.put(4);
intBuffer.put(5);
intBuffer.put(6);
intBuffer.put(7);
intBuffer.put(8);
intBuffer.put(9);
intBuffer.put(10);
// 放入第11个元素时会溢出
try {
intBuffer.put(11);
} catch (BufferOverflowException e) {
System.out.println("here should be overflow");
e.printStackTrace();
}
// 写模式切换到读模式
intBuffer.flip();
// 从buffer中读取数据
int one = intBuffer.get();
System.out.println("read from IntBuffer: should be 1, actually: " + one);
// 重定向读取位置为0
intBuffer.rewind();
one = intBuffer.get();
System.out.println("read from IntBuffer: should be 1, actually: " + one);
//intBuffer.get(new int[9]);
// 读模式切换到写模式
// 将position设置为0, limit设置为capacity
// 如果不想继续读取未被读取的数据,intBuffer.clear();
intBuffer.compact();
intBuffer.put(11);
intBuffer.flip();
// 读取第一个元素,应该是2
int two = intBuffer.get();
System.out.println("read from IntBuffer: should be 2, actually: " + two);
Buffer是JavaNIO中的关键组件,用于Channel的读写操作。它包括多种类型的Buffer如ByteBuffer等,通过四步(写入、flip、读取、clear/compact)进行数据操作。Buffer有capacity、position、limit和mark四个属性,分别表示最大容量、当前读写位置、可读取限制和标记。在读写模式下,position和limit的含义不同。Buffer.flip()用于切换读写模式,clear()用于重置,compact()则将未读数据移到开始并更新position。
1126

被折叠的 条评论
为什么被折叠?



