天天看点

通道之间的数据传输 – Java NIO

通道之间的数据传输 – Java NIO

与通常在输入源和输出目标之间发生 IO 的普通 Java 应用程序一样,在 NIO 中,您也可能需要非常频繁地将数据从一个通道传输到另一通道。 文件数据从一个地方到另一个地方的批量传输非常普遍,以至于 ​

​FileChannel​

​ 类添加了两种优化方法,以使其效率更高。

​FileChannel.transferTo()​

​ 和 ​

​FileChannel.transferFrom()​

​ 方法

​transferTo()​

​ 和 ​

​transferFrom()​

​ 方法使您可以将一个通道交叉连接到另一个通道,而无需通过中间缓冲区传递数据。 这些方法仅在 ​

​FileChannel​

​ 类上存在,因此,在通道间传输中涉及的通道之一必须是 ​

​FileChannel​

​ 。

public abstract class FileChannel
        extends AbstractChannel
        implements ByteChannel, GatheringByteChannel, ScatteringByteChannel {
        // There are more other methods
        public abstract long transferTo (long position, long count, WritableByteChannel target);
        public abstract long transferFrom (ReadableByteChannel src, long position, long count);
}      

您无法在套接字通道之间进行直接传输,但是套接字通道实现了 ​

​WritableByteChannel​

​ 和 ​

​ReadableByteChannel​

​ ,因此可以使用 ​

​transferTo()​

​ 将文件的内容传输到套接字,或者可以使用 ​

​transferFrom()​

​ 从套接字直接读取数据到文件中。

另外,请记住,如果在传输过程中遇到问题,这些方法可能会抛出 ​

​java.io.IOException​

​ 。

通道间数据传输示例

package com.howtodoinjava.nio;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;

public class ChannelTransferExample 
{
  public static void main(String[] argv) throws Exception 
  {
    //Input files
    String[] inputFiles = new String[]{"inputFile1.txt","inputFile2.txt","inputFile3.txt"};

    //Files contents will be written in these files
    String outputFile = "outputFile.txt";

    //Get channel for output file
    FileOutputStream fos = new FileOutputStream(new File(outputFile));
    WritableByteChannel targetChannel = fos.getChannel();

    for (int i = 0; i < inputFiles.length; i++)
    {
      //Get channel for input files
      FileInputStream fis = new FileInputStream(inputFiles[i]);
      FileChannel inputChannel = fis.getChannel();

      //Transfer data from input channel to output channel
      inputChannel.transferTo(0, inputChannel.size(), targetChannel);

      //close the input channel
      inputChannel.close();
      fis.close();
    }

    //finally close the target channel
    targetChannel.close();
    fos.close();
  }
}