Java Nio 简明教程

Java NIO - Gather

众所周知,与 Java 的传统 IO API 相比,Java NIO 是一个针对数据 IO 操作进行了更优化的 API。Java NIO 提供的另外一项支持是将数据从多个缓冲区读/写到通道。这种多读多写支持称为分散和聚集,其中多个缓冲区从读取数据时单个通道中分散,而多个缓冲区在写入数据时从单个通道中聚集。

As we know that Java NIO is a more optimized API for data IO operations as compared to the conventional IO API of Java.One more additional support which Java NIO provides is to read/write data from/to multiple buffers to channel.This multiple read and write support is termed as Scatter and Gather in which data is scattered to multiple buffers from single channel in case of read data while data is gathered from multiple buffers to single channel in case of write data.

为了实现从通道的多读多写,Java NIO 为读取和写入数据提供了 ScatteringByteChannel 和 GatheringByteChannel API,如以下示例所示。

In order to achieve this multiple read and write from channel there is ScatteringByteChannel and GatheringByteChannel API which Java NIO provides for read and write the data as illustrate in below example.

GatheringByteChannel

write to multiple channels − 在此示例中,我们让多个缓冲区中的数据写入一个管道中。为此,再次分配了多个缓冲区,并将这些缓冲区添加到缓冲区类型数组中。然后将此数组作为参数传递给 GatheringByteChannel write() 方法,该方法依次从数组中的多个缓冲区写入数据。这里需要记住的一点是,只写入缓冲区的 position 和 limit 之间的数据。

write to multiple channels − In this we made to write data from multiple buffers into a single channel.For this again multiple buffers are allocated and are added to a buffer type array.Then this array is passed as parameter to the GatheringByteChannel write() method which then writes data from the multiple buffers in the sequence the buffers occur in the array.One point to remember here is only the data between the position and the limit of the buffers are written.

以下示例显示了如何在 Java NIO 中执行数据收集

The following example shows how data gathering is performed in Java NIO

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.GatheringByteChannel;

public class GatherExample {
   private static String FILENAME = "C:/Test/temp.txt";
   public static void main(String[] args) {
      String stream1 = "Gather data stream first";
      String stream2 = "Gather data stream second";
      ByteBuffer bLen1 = ByteBuffer.allocate(1024);
      ByteBuffer bLen2 = ByteBuffer.allocate(1024);
      // Next two buffer hold the data we want to write
      ByteBuffer bstream1 = ByteBuffer.wrap(stream1.getBytes());
      ByteBuffer bstream2 = ByteBuffer.wrap(stream2.getBytes());
      int len1 = stream1.length();
      int len2 = stream2.length();
      // Writing length(data) to the Buffer
      bLen1.asIntBuffer().put(len1);
      bLen2.asIntBuffer().put(len2);
      System.out.println("Gathering : Len1 = " + len1);
      System.out.println("Gathering : Len2 = " + len2);
      // Write data to the file
      try {
         FileOutputStream out = new FileOutputStream(FILENAME);
         GatheringByteChannel gather = out.getChannel();
         gather.write(new ByteBuffer[] {bLen1, bLen2, bstream1, bstream2});
         out.close();
         gather.close();
      }
      catch (FileNotFoundException exObj) {
         exObj.printStackTrace();
      }
      catch(IOException ioObj) {
         ioObj.printStackTrace();
      }
   }
}

Output

Gathering : Len1 = 24
Gathering : Len2 = 25

最后可以得出结论,如果正确使用,Java NIO 中的分散/聚集方法是一种经过优化且可以多任务处理。它允许你将分离出读入多个存储桶中的数据或将不同数据块组装成一个整体的繁琐工作委托给操作系统。毫无疑问,这节省了时间,并且通过避免缓冲区副本更有效地使用了操作系统,并减少了需要编写和调试的代码量。

In last it can be concluded that scatter/gather approach in Java NIO is introduced as an optimized and multitasked when used properly.It allows you to delegate to the operating system the grunt work of separating out the data you read into multiple buckets, or assembling disparate chunks of data into a whole.No doubt this saves time and uses operating system more efficiently by avoiding buffer copies, and reduces the amount of code need to write and debug.