欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 宝鼎售后问题提交 | 后台管理


新闻资讯

MENU

软件开发知识

如 ByteBuffer 中的几个 put 方法: // 填充一个 byte 值public a 次  来源:宝鼎软件 时间:2018-02-12

原文出处: JavaDoop

本文将先容 Java NIO 中三大组件 Buffer、Channel、Selector 的利用。

原来要一起先容非阻塞 IO 和 JDK7 的异步 IO 的,不外因为之前的文章真的太长了,有点影响读者阅读,所以这里将它们放到另一篇文章中举办先容。

Buffer

一个 Buffer 本质上是内存中的一块,我们可以将数据写入这块内存,之后从这块内存获取数据。

java.nio 界说了以下几个 Buffer 的实现,这个图读者应该也在不少处所见过了吧。

其实焦点是最后的 ByteBuffer,前面的一大串类只是包装了一下它罢了,我们利用最多的凡是也是 ByteBuffer。

我们应该将 Buffer 领略为一个数组,IntBuffer、CharBuffer、DoubleBuffer 等别离对应 int[]、char[]、double[] 等。

MappedByteBuffer 用于实现内存映射文件,也不是本文存眷的重点。

我以为操纵 Buffer 和操纵数组、类集差不多,只不外大部门时候我们都把它放到了 NIO 的场景内里来利用罢了。下面先容 Buffer 中的几个重要属性和几个重要要领。

position、limit、capacity

就像数组有数组容量,每次会见元素要指定下标,Buffer 中也有几个重要属性:position、limit、capacity。

最好领略的虽然是 capacity,它代表这个缓冲区的容量,一旦设定就不行以变动。好比 capacity 为 1024 的 IntBuffer,代表其一次可以存放 1024 个 int 范例的值。一旦 Buffer 的容量到达 capacity,需要清空 Buffer,才气从头写入值。

position 和 limit 是变革的,我们别离看下读和写操纵下,它们是如何变革的。

position 的初始值是 0,每往 Buffer 中写入一个值,position 就自动加 1,代表下一次的写入位置。读操纵的时候也是雷同的,每读一个值,position 就自动加 1。

从写操纵模式到读操纵模式切换的时候(flip),position 城市归零,这样就可以从新开始读写了。

Limit:写操纵模式下,limit 代表的是最大能写入的数据,这个时候 limit 便是 capacity。写竣事后,切换到读模式,此时的 limit 便是 Buffer 中实际的数据巨细,因为 Buffer 不必然被写满了。

初始化 Buffer

每个 Buffer 实现类都提供了一个静态要领 allocate(int capacity) 辅佐我们快速实例化一个 Buffer。如:

ByteBuffer byteBuf = ByteBuffer.allocate(1024);
IntBuffer intBuf = IntBuffer.allocate(1024);
LongBuffer longBuf = LongBuffer.allocate(1024);
// ...

别的,我们常常利用 wrap 要领来初始化一个 Buffer。

public static ByteBuffer wrap(byte[] array) {
    ...
}

填充 Buffer

各个 Buffer 类都提供了一些 put 要领用于将数据填充到 Buffer 中,如 ByteBuffer 中的几个 put 要领:

// 填充一个 byte 值
public abstract ByteBuffer put(byte b);
// 在指定位置填充一个 int 值
public abstract ByteBuffer put(int index, byte b);
// 将一个数组中的值填充进去
public final ByteBuffer put(byte[] src) {...}
public ByteBuffer put(byte[] src, int offset, int length) {...}

上述这些要领需要本身节制 Buffer 巨细,不能高出 capacity,高出会抛 java.nio.BufferOverflowException 异常。

对付 Buffer 来说,另一个常见的操纵中就是,我们要未来自 Channel 的数据填充到 Buffer 中,在系统层面上,这个操纵我们称为读操纵,因为数据是从外部(文件或网络等)读到内存中。

int num = channel.read(buf);

上述要了解返回从 Channel 中读入到 Buffer 的数据巨细。

提取 Buffer 中的值

前面先容了写操纵,每写入一个值,position 的值都需要加 1,所以 position 最后会指向最后一次写入的位置的后头一个,假如 Buffer 写满了,那么 position 便是 capacity(position 从 0 开始)。

假如要读 Buffer 中的值,需要切换模式,从写入模式切换到读出模式。留意,凡是在说 NIO 的读操纵的时候,我们说的是从 Channel 中读数据到 Buffer 中,对应的是对 Buffer 的写入操纵,初学者需要理清楚这个。

挪用 Buffer 的 flip() 要领,可以举办模式切换。其实这个要领也就是配置了一下 position 和 limit 值而已。

public final Buffer flip() {
    limit = position; // 将 limit 配置为实际写入的数据数量
    position = 0; // 重置 position 为 0
    mark = -1; // mark 之后再说
    return this;
}