一、操作总结

limit(), limit(10)等 其中读取和设置这 4 个属性的方法的命名和 jQuery 中的 val(),val(10)类似,一个负 责 get,一个负责 set
reset() 把 position 设置成 mark 的值,相当于之前做过一个标记,现在要退回到之前标记的地方
clear() position = 0;limit = capacity;mark = -1; 有点初始化的味道,但是并不影响底 层 byte 数组的内容
flip() limit = position;position = 0;mark = -1; 也就是让 flip 之后的 position 到 limit 这块区域变成之前的 0 到 position 这块,就是将一个处于存数据状态的缓冲区变为一个处于准备取数据的状态
rewind() 把 position 设为 0,mark 设为-1,不改变 limit 的值
remaining() return limit - position;返回 limit 和 position 之间相对位置差
hasRemaining () return position < limit 返回是否还有未读内容
compact() 把从 position 到 limit 中的内容移到 0 到 limit-position 的区域内,position 和 li
mit 的取值也分别变成 limit-position、capacity。如果先将 positon 设置到 limit,再 c
ompact,那么相当于 clear()
get() 相对读,从 position 位置读取一个 byte,并将 position+1,为下次读写作准备
get(int index) 绝对读,读取 byteBuffer 底层的 bytes 中下标为 index 的 byte,不改变 position
get(byte[] dst, int offset, int len gth) 从 position 位置开始相对读,读 length 个 byte,并写入 dst 下标从 offset 到 offs
et+length 的区域
put(byte b) 相对写,向 position 的位置写入一个 byte,并将 postion+1,为下次读写作准备
put(int index, byte b) 绝对写,向 byteBuffer 底层的 bytes 中下标为 index 的位置插入 byte b,不改变 position
put(ByteBuffer src) 用相对写,把 src 中可读的部分(也就是 position 到 limit)写入此 byteBuffer
put(byte[] src, int offset, int length) 从 src 数组中的 offset 到 offset+length 区域读取数据并使用相对写,写入此 byteBuffer

二、Buffer读写

向 Buffer 中写数据

写数据到 Buffer 有两种方式:
读取 Channel 写到 Buffer。
通过 Buffer 的 put()方法写到 Buffer 里。
从 Channel 写到 Buffer 的例子
int bytesRead = inChannel.read(buf); //read into buffer.
通过 put 方法写 Buffer 的例子:
buf.put(127);

put 方法

有很多版本,允许你以不同的方式把数据写入到 Buffer 中。
例如, 写到一个 指定的位置,或者把一个字节数组写入到 Buffer。
比如: put(byte b) 相对写,向 position 的位置写入一个 byte,并将 postion+1,为下次读写 作准备。

flip()方法

flip 方法将 Buffer 从写模式切换到读模式。调用 flip()方法会将 position 设回 0,并将 limit 设置成之前 position 的值。

position 现在用于标记读的位置,limit 表示之前写进了多少个 byte、char 等
现在能读取多少个 byte、char 等

从 Buffer 中读数据

从 Buffer 中读取数据有两种方式:
1. 从 Buffer 读取数据写入到 Channel。
2. 使用 get()方法从 Buffer 中读取数据。
从 Buffer 读取数据到 Channel 的例子:
int bytesWritten = inChannel.write(buf);
使用 get()方法从 Buffer 中读取数据的例子
byte aByte = buf.get();

get 方法

有很多版本,允许你以不同的方式从 Buffer 中读取数据。
例如,从指定 position读取,或者从 Buffer 中读取数据到字节数组,
比如 get()属于相对读,从 position 位置读取一个 byte,并将 position+1,为下次读写作准备;

Buffer 读写数据常见步骤

  1. 写入数据到 Buffer
    2. 调用 flip()方法
    3. 从 Buffer 中读取数据
    4. 调用 clear()方法或者 compact()方法,准备下一次的写入
    当向 buffer 写入数据时,buffer 会记录下写了多少数据。一旦要读取数据,需要通过 flip() 方法将Buffer从写模式切换到读模式。
    在读模式下,可以读取之前写入到buffer的所有数据。 一旦读完了所有的数据,就需要清空缓冲区,让它可以再次被写入。
    有两种方式能清空 缓冲区
    调用 clear()或 compact()方法。clear()方法会清空整个缓冲区。compact()方法只会清 除已经读过的数据。

    绝对读写

    put(int index, byte b)
    绝对写,向 byteBuffer 底层的 bytes 中下标为 index 的位置插入byte b,不改变 position 的值。
    get(int index)
    属于绝对读,读取 byteBuffer 底层的 bytes 中下标为 index 的 byte,不改变 position。
    rewind()方法
    Buffer.rewind()将 position 设回 0,所以你可以重读 Buffer 中的所有数据。limit 保持不变, 仍然表示能从 Buffer 中读取多少个元素(byte、char 等)。

    Buffer 被清空

    clear()与 compact()方法
    一旦读完Buffer中的数据,需要让Buffer准备好再次被写入。可以通过clear()或compact() 方法来完成。
    如果调用的是 clear()方法,position 将被设回 0,limit 被设置成 capacity 的值。换句话
    说,Buffer 被清空了。Buffer 中的数据并未清除,只是这些标记告诉我们可以从哪里开始往
    Buffer 里写数据。
    如果 Buffer 中有一些未读的数据,调用 clear()方法,数据将“被遗忘”,意味着不再有任 何标记会告诉你哪些数据被读过,哪些还没有。
    如果 Buffer 中仍有未读的数据,且后续还需要这些数据,但是此时想要先写些数据, 那么使用 compact()方法。compact()方法将所有未读的数据拷贝到 Buffer 起始处。然后将 position 设到最后一个未 读元素正后面。limit 属性依然像 clear()方法一样,设置成 capacity。现在 Buffer 准备好写数 据了,但是不会覆盖未读的数据。

    mark()与 reset()方法

    通过调用 Buffer.mark()方法,可以标记 Buffer 中的一个特定 position。之后可以通过调用 Buffer.reset()方法恢复到这个 position。
    例如:
    buffer.mark();//call buffer.get() a couple of times, e.g. during parsing.
    buffer.reset(); //set position back to mark.

    equals()与 compareTo()方法

    可以使用 equals()和 compareTo()方法比较两个Buffer。
    equals()
    当满足下列条件时,表示两个 Buffer 相等:
    1. 有相同的类型(byte、char、int 等)。
    2. Buffer 中剩余的 byte、char 等的个数相等。
    3. Buffer 中所有剩余的 byte、char 等都相同。
    如你所见,equals 只是比较 Buffer 的一部分,不是每一个在它里面的元素都比较。实际
    上,它只比较 Buffer 中的剩余元素。
    compareTo()方法
    compareTo()方法比较两个 Buffer 的剩余元素(byte、char 等), 如果满足下列条件,则
    认为一个 Buffer“小于”另一个 Buffer:
    1. 第一个不相等的元素小于另一个 Buffer 中对应的元素 。
    2. 所有元素都相等,但第一个 Buffer 比另一个先耗尽(第一个 Buffer 的元素个数比另一个少)。