学下下网络编程中常用的两个Buffer,ByteBuffer和ByteBuf,接下来会分析两者的细节及总结。
一.ByteBuffer
ByteBuffer是JDK NIO中提供的java.nio.Buffer, 在内存中预留指定大小的存储空间来存放临时数据,其他Buffer 的子类有:CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer 和 ShortBuffer
1. Buffer
ByteBuffer继承Buffer,Buffer中定义的成员变量。
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public abstract class Buffer {
// Invariants: mark <= position <= limit <= capacity
private int mark = -1;
private int position = 0;
private int limit;
private int capacity;
// Used only by direct buffers
// NOTE: hoisted here for speed in JNI GetDirectBufferAddress
long address;
每个Buffer都有以下的属性:
capacity
这个Buffer最多能放多少数据。capacity在buffer被创建的时候指定。
limit
在Buffer上进行的读写操作都不能越过这个下标。当写数据到buffer中时,limit一般和capacity相等,当读数据时,
limit代表buffer中有效数据的长度。
position
读/写操作的当前下标。当使用buffer的相对位置进行读/写操作时,读/写会从这个下标进行,并在操作完成后,
buffer会更新下标的值。
mark
一个临时存放的位置下标。调用mark()会将mark设为当前的position的值,以后调用reset()会将position属性设
置为mark的值。mark的值总是小于等于position的值,如果将position的值设的比mark小,当前的mark值会被抛弃掉。
这些属性总是满足以下条件:
0 <= mark <= position <= limit <= capacity
import java.nio.ByteBuffer;
public class ByteBufferTest {
public static void main(String[] args) {
//实例初始化
ByteBuffer buffer = ByteBuffer.allocate(100);
String value ="Netty";
buffer.put(value.getBytes());
buffer.flip();
byte[] vArray = new byte[buffer.remaining()];
buffer.get(vArray);
System.out.println(new String(vArray));
}
}
我们看下调用flip()操作前后的对比
+--------------------+-----------------------------------------------------------+
| Netty | |
+--------------------+-----------------------------------------------------------+
| | |
0 position limit = capacity
ByteBuffer flip()操作之前
+--------------------+-----------------------------------------------------------+
| Netty | |
+--------------------+-----------------------------------------------------------+
| | |
position limit capacity
ByteBuffer flip()操作之后
3.Buffer常用的函数
clear()
把position设为0,把limit设为capacity,一般在把数据写入Buffer前调用。
public final Buffer clear() {
position = 0;
limit = capacity;
mark = -1;
return this;
}
flip()
把limit设为当前position,把position设为0,一般在从Buffer读出数据前调用。
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
rewind()
把position设为0,limit不变,一般在把数据重写入Buffer前调用。
public final Buffer rewind() {
position = 0;
mark = -1;
return this;
}
mark()
设置mark的值,mark=position,做个标记。
reset()
还原标记,把mark的值赋值给position。
4.ByteBuffer实例化