ByteBuffer是在nio中常用的一个buffer,可以理解为就是一个byte的数组,用于存放数据的同时增加了一些属性对这个byte数组进行一些管理
重要属性
属性 | 说明 |
---|---|
byte[] hb | 存数据的字节数组 |
int mark | 临时记录position,与mark()、reset()两个方法配合使用 |
int position | hb数组的当前指针 |
int limit | 写模式:可写的字节限制;读模式:可以读的字节限制 |
int capacity | buffer的大小 |
int offset | 和position类似,也是指向hb的指针,当不一定相等 |
创建方法
一般是用下方四个静态方法来创建
方法 | 说明 |
---|---|
allocate(int capacity) | capacity指定了属性limit和capacity的大小,也就是说创建后就是一个写模式,可开始往里写数据 limit=capacity this.capacity=capacity |
allocateDirect(int capacity) | 和allocate一样的效果,不同的是allocate分配的堆内存,而此方法分配的堆外内存 |
wrap(byte[] array,int offset, int length) | 分配空间同时给数组赋初始值 hb=array position=offset limit=offset+length |
wrap(byte[] array) | 调用wrap(array, 0, array.length) |
查询属性方法
方法 | 说明 |
---|---|
position() | 返回position |
limit() | 返回limit |
capacity() | 返回capacity |
hasRemaining() | 一般用于读模式,用while循环判断是都读到了数组尽头 return position < limit; |
remaining() | 功能和hasRemaining()类似,>0有数据可读,<0数据已读完 return limit - position; |
存取方法
加粗的为常用方法
方法 | 说明 |
---|---|
put(byte[] src, int offset, int length) | 把src里offset到结尾的数据放入hb 关键代码如下: int end = offset + length; for (int i = offset; i < end; i++) |
put(byte[] src) | 调用put(src, 0, src.length) |
put(ByteBuffer src) | 配合flip()方法使用,切换到读模式,把所有内容放入hb int n = src.remaining(); |
get(byte[] dst, int offset, int length) | 去hb数据放到dst中 |
get(byte[] dst) | 调方法get(dst, 0, dst.length) |
byte[] array() | 直接返回hb |
指针移动方法
方法 | 说明 |
---|---|
flip() | 切换为读模式 limit = position; |
clear() | 切换为写模式 position = 0; limit = capacity; |
hasRemaining() | return position < limit; 一般用于读模式,用while循环判断是都读到了数组尽头 |
mark() | 记录当前position mark = position; |
reset() | positon切换为mark记录的指针。 使用前必须调用过mark()方法,不然会排除异常 position = mark; |
rewind() | position归0,可进行重读或重写 position = 0; |
position(int newPosition) | 赋值新的position position = newPosition |
limit(int newLimit) | 赋值新的limit limit = newLimit; |
使用示例
创建buffer->写数据到buffer->读出buffer数据传给channel
public class FileChannelTest {
public static void main(String[] args) throws IOException {
//append默认false,当传入true时会每次追加内容再最后,false即代表覆盖
FileOutputStream fileOutputStream = new FileOutputStream("D:\\workspace\\learn\\free\\src\\main\\resources\\fc.txt", false);
FileChannel channel = fileOutputStream.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
//写模式,写入内容到buffer
buffer.put("Hello ByteBuffer".getBytes());
//切换读模式,读出buffer数据传给channel,channel通道连接着文件
buffer.flip();
while (buffer.hasRemaining()){
//write方法调用时,会修改buffer的position一直往后指
channel.write(buffer);
}
//变回初始状态
buffer.clear();
channel.close();
}
}
mark、reset方法使用示例
public class ByteBufferMarkTest {
public static void main(String[] args) throws IOException {
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put("abc".getBytes());
//在c的位置做标记
buffer.mark();
buffer.put("123".getBytes());
//标记回到c
buffer.reset();
buffer.put("456".getBytes());
buffer.flip();
byte[] dst = new byte[buffer.remaining()];
buffer.get(dst);
//输出abc456,把123的值覆盖了
System.out.println(new String(dst));
}
}