Java Nio 简明教程

Java NIO - Gather

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

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

GatheringByteChannel

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

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