Java NIO - 散射



众所周知,与 Java 的传统 IO API 相比,Java NIO 是一个更优化的数据 IO 操作 API。Java NIO 提供的另一个额外支持是从/向多个缓冲区读/写数据到通道。这种多读写支持称为散射和聚集,其中在读取数据的情况下,数据从单个通道散射到多个缓冲区,而在写入数据的情况下,数据从多个缓冲区聚集到单个通道。

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

ScatteringByteChannel

从多个通道读取 - 在此,我们从单个通道读取数据到多个缓冲区。为此,分配多个缓冲区并将其添加到缓冲区类型数组中。然后将此数组作为参数传递给 ScatteringByteChannel read() 方法,该方法随后按数组中缓冲区的顺序从通道写入数据。缓冲区满后,通道继续填充下一个缓冲区。

以下示例演示了如何在 Java NIO 中执行数据的散射。

C:/Test/temp.txt

Hello World!
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ScatteringByteChannel;

public class ScatterExample {	
   private static String FILENAME = "C:/Test/temp.txt";
   public static void main(String[] args) {
      ByteBuffer bLen1 = ByteBuffer.allocate(1024);
      ByteBuffer bLen2 = ByteBuffer.allocate(1024);
      FileInputStream in;
      try {
         in = new FileInputStream(FILENAME);
         ScatteringByteChannel scatter = in.getChannel();
         scatter.read(new ByteBuffer[] {bLen1, bLen2});
         bLen1.position(0);
         bLen2.position(0);
         int len1 = bLen1.asIntBuffer().get();
         int len2 = bLen2.asIntBuffer().get();
         System.out.println("Scattering : Len1 = " + len1);
         System.out.println("Scattering : Len2 = " + len2);
      } 
      catch (FileNotFoundException exObj) {
         exObj.printStackTrace();
      }
      catch (IOException ioObj) {
         ioObj.printStackTrace();
      }
   }
}

输出

Scattering : Len1 = 1214606444
Scattering : Len2 = 0

最后可以得出结论,在正确使用时,Java NIO 中的散射/聚集方法被引入作为一种优化和多任务方法。它允许您将读取数据分成多个存储桶或将分散的数据块组装成一个整体的繁重工作委托给操作系统。毫无疑问,这节省了时间,并通过避免缓冲区复制更有效地利用了操作系统,并减少了需要编写和调试的代码量。

广告