NIO的buffer使用

已转移

Java NIO 的前生今世 之三 NIO Buffer 详解

https://segmentfault.com/a/1190000006824155

Buffer 有三个属性:

  • capacity

  • position

  • limit

capacity是分配时确定的,是一个常量;position 和 limit 的含义与 Buffer 处于读模式或写模式有关,

写模式时,position是当前已写到的位置,limit是最大可写到的位置

读模式时,position是当前已读到的位置,limit是最大可读到的位置

limit - position 表示此时还可以写入/读取多少单位的数据,如果继续读或写就会报错。

写入数据到 Buffer

int bytesRead = inChannel.read(buf); //from channel write into buffer.
buf.put(127);

从 Buffer 中读取数据

int bytesWritten = inChannel.write(buf); //read from buffer into channel.
byte aByte = buf.get();

重置 position

Buffer.rewind()方法可以重置 position 的值为0, 因此我们可以重新读取/写入 Buffer 了。

rewind() 主要针对于读模式. 在读模式时, 读取到 limit 后, 可以调用 rewind() 方法, 将读 position 置为0

关于 mark()和 reset()

我们可以通过调用 Buffer.mark()将当前的 position 的值保存起来, 随后可以通过调用 Buffer.reset()方法将 position 的值回复回来.

flip, rewind 和 clear 的区别

flip

flip 方法源码
public final Buffer flip() {
    limit = position;
    position = 0;
    mark = -1;
    return this;
}

Buffer 的读/写模式共用一个 position 和 limit 变量.
当从写模式变为读模式时, 原先的 写 position 就变成了读模式的 limit.

rewind

rewind 方法源码
public final Buffer rewind() {
    position = 0;
    mark = -1;
    return this;
}

rewind, 即倒带, 这个方法仅仅是将 position 置为0.

clear

clear 方法源码:
public final Buffer clear() {
    position = 0;
    limit = capacity;
    mark = -1;
    return this;
}

根据源码我们可以知道, clear 将 positin 设置为0, 将 limit 设置为 capacity.
clear 方法使用场景:

    • 在一个已经写满数据的 buffer 中, 调用 clear, 可以从头读取 buffer 的数据.

    • 为了将一个 buffer 填充满数据, 可以调用 clear, 然后一直写入, 直到达到 limit.

读或写模式实际上也是改变pos、lim的值,上面的几个方法都是改变参数的值,对buf中的数据不会有影响,每次都会将mark重置为-1。

mark <= position <= limit <= capacity ,满足这个不等式,运行时才可以不报错。

Buffer 的比较

我们可以通过 equals() 或 compareTo() 方法比较两个 Buffer, 当且仅当如下条件满足时, 两个 Buffer 是相等的:

  • 两个 Buffer 是相同类型的

  • 两个 Buffer 的剩余的数据个数是相同的

  • 两个 Buffer 的剩余的数据都是相同的.

通过上述条件我们可以发现, 比较两个 Buffer 时, 并不是 Buffer 中的每个元素都进行比较, 而是比较 Buffer 中剩余的元素.

原文地址:https://www.cnblogs.com/xyfaneast/p/10740398.html