Java Nio Buffer 八

2017/05/21 Java

Java Nio Buffer 八

Scatter/Gather

通道提供了一种被称为 Scatter/Gather 的重要新功能(有时也被称为矢量 I/O)。Scatter/Gather 它是指在多个缓冲区上实现一个简单的 I/O 操作。大多数现代操作系统都支持本地矢量 I/O(native vectored I/O)。在一个通道上请求一个 Scatter/Gather 操作时,会通过本地调用来直接填充或抽取缓冲区。

实现Scatter和Gather的接口代码如下:

public interface ScatteringByteChannel
    extends ReadableByteChannel
{
    public long read (ByteBuffer [] dsts)
        throws IOException;
    public long read (ByteBuffer [] dsts, int offset, int length)
        throws IOException;
}
public interface GatheringByteChannel
    extends WritableByteChannel
{
    public long write(ByteBuffer[] srcs)
        throws IOException;
    public long write(ByteBuffer[] srcs, int offset, int length)
        throws IOException;
}

类的UML图如下:
图一

各个方法都提供了一种缓冲区队列作为参数的新方法,也提供了一种带Offset和length的方式。如下,假如channel 链接到了一个有48字节数据等待读取的socket上:

ByteBuffer header = ByteBuffer.allocateDirect (10);
ByteBuffer body = ByteBuffer.allocateDirect (80);
ByteBuffer [] buffers = { header, body };
int bytesRead = channel.read (buffers);

read( )方法返回,bytesRead 就被赋予值 48,header 缓冲区将包含前 10 个从通道读 取的字节而 body 缓冲区则包含接下来的 38 个字节。Gather 操作类似。

一个具体的例子如下: 图二

图三

带有offset 和 length 参数版本的 read( ) 和 write( )方法使得我们可以使用缓冲区阵列的子集 缓冲区。这里的 offset 值指哪个缓冲区将开始被使用,而不是指数据的 offset。这里的 length 参数指示要使用的缓冲区数量。
Scatter/Gather 是一个极其强大的工具。通过委托操作系统来完成具体任务:将读取到的数据分开存放到多个存储桶(bucket)或者将不同的数据区块合并成一个整体。操作系统的这种操作已经高度优化过了。

第一次知道原来还有一种I/O叫向量I/O。看着NIO,有种把JAVA写成C的感觉。

Show Disqus Comments

Search

    Table of Contents