java.nio.ByteBuffer中的flip()、rewind()、compact()等方法的使用和区别

java.nio.ByteBuffer

1. ByteBuffer中的参数position、limit、capacity、mark含义:

position:表示当前指针的位置(下一个要操作的数据元素的位置)

limit:表示当前数组最大的使用量,即有效位置的EOF位置(缓冲区数组中不可操作的下一个元素的位置,limit<=capacity)

capacity:表示缓冲区最大容量(缓冲区数据的总长度)

mark:用于记录当前position的前一个位置或者默认是-1

2. ByteBuffer中常用方法含义:

reset():把position设置为mark的值,相当于之前做过一个标记,现在回退到之前标记的地方。

clear():将参数设置为position=0,limit=capacity,mark=-1,类似于初始化,但并不影响底层byte数组的内容(注意:clear只是把指针移到位置0,并没有真正清空数据)。

flip():将参数设置为limit=position,position=0,mark=-1,翻转,即将未翻转之前0到position之间的数据放置到翻转之后的position(即0)到limit之间的这块区域,翻转将缓冲区的状态由存数据变为准备取数据(注意:将当前位置设置为EOF,指针位置指向0)。

rewind():将参数设置为position=0,mark=-1,limit的值不变(注意:指针指向0)。

remaining():return limit - position,即返回limit和position之间的相对位置差。

hasRemaining():return position < limit,即返回是否还有未读内容。

compact():将position与limit之间的内容移到0与(limit - position)之间的区域,position的值变为limit - position,limit的值变为capacity;如果先将position的设置到limit,再执行compact操作,就相当于clear操作(注意:compact表示压缩数据,例如当前EOF是6,当前指针指向2即下标0、1位置的数据已经写出,此时执行compact方法就是将下标2、3、4、5的数据移动到下标0、1、2、3的位置,指针指向下标4的位置,然后从4的位置继续写入数据。写完后,把指针移动到0,再写出,然后再执行compact操作,如此反复......)。

示例:初始化一个ByteBuffer,缓冲区最大容量为10,开始指针指向下标0即position=0。

   然后写入6字节数据,写入完成后下标0、1、2、3、4、5位置有实际写入的数据,下标6、7、8、9位置为默认值0。

   此时,指针指向6,即position=6,limit(6)方法会将当前位置设为EOF位置。

   最后,读取数据时读取到EOF位置就会结束。

示例代码

 1 import java.nio.ByteBuffer;
 2 
 3 public class ByteBufferTest {
 4 
 5     public static void main(String[] args) {
 6 
 7         //分配10字节大小内存空间
 8         ByteBuffer buffer = ByteBuffer.allocate(10);
 9         //输出初始化后position的值
10         System.out.println("初始化position : " + buffer.position());
11         //输出初始化收limit的值
12         System.out.println("初始化limit : " + buffer.limit());
13         //输出初始化后capacity的值
14         System.out.println("初始化capacity : " + buffer.capacity());
15         //输出初始化后ByteBuffer内容
16         printBuffer(buffer);
17 
18         //调用rewind()之前指针指向下标9即位置10,已经是最大容量
19         //调用rewind()之后将指针移动到下标0即位置1
20         buffer.rewind();
21         System.out.println("position:" + buffer.position() + ",limit:" + buffer.limit() + ",capacity:" + buffer.capacity());
22         //执行写入操作,指针会自动移动
23         buffer.putChar('a');
24         //输出指针position,指针指向下标2即位置3
25         System.out.println("写入字符'a'后,position位置为:" + buffer.position());
26         buffer.putChar('啊');
27         //输出指针position,指针指向下标4即位置5
28         System.out.println("写入字符'啊'后,position位置为:" + buffer.position());
29 
30         //将当前位置设置为EOF,指针移动到下标0即位置1
31         buffer.flip();
32         System.out.println("position:" + buffer.position() + ",limit:" + buffer.limit() + ",capacity:" + buffer.capacity());
33         //上一行代码相当于下面两句
34         //buffer.limit(4);
35         //buffer.position(0);
36 
37         //输出ByteBuffer内容,即0 61 55 4a
38         printBuffer(buffer);
39         //将指针移动到下标1即位置2
40         buffer.position(1);
41         //进行compact压缩操作,compact操作会将EOF位置重置为最大容量10
42         //注意:该压缩操作是将下标1即位置2到位置4的值移动到位置1到位置3,位置4上的值4a不变
43         buffer.compact();
44         //输出ByteBuffer内容,即61 55 4a 4a 0 0 0 0 0 0(注意:未覆盖到的位置4的值4a不变)
45         printBuffer(buffer);
46 
47         //注意:执行压缩compact操作后指针指向下标3即位置4,继续写入数据时会覆盖数据
48         System.out.println(buffer.position());
49     }
50 
51     /**
52      * 输出ByteBuffer内容
53      * @param buffer
54      */
55     public static void printBuffer(ByteBuffer buffer){
56 
57         //记录当前位置
58         int position = buffer.position();
59         //指针移动到0
60         buffer.position(0);
61         //循环输出每个字节内容
62         for(int i = 0;i < buffer.limit();i++){
63             //读取操作,指针会自动移动
64             byte b = buffer.get();
65             System.out.print(Integer.toHexString(b));
66         }
67         //指针再移动到标记位置
68         buffer.position(position);
69         System.out.println();
70     }
71 }

输出结果

初始化position : 0
初始化limit : 10
初始化capacity : 10
0000000000
position:0,limit:10,capacity:10
写入字符'a'后,position位置为:2
写入字符'啊'后,position位置为:4
position:0,limit:4,capacity:10
061554a
61554a4a000000
3

 

posted on 2019-09-05 15:47  峰的季节  阅读(5909)  评论(0编辑  收藏  举报