可以使Java中的有时例行任务变得更加轻松的JDK 9的次要补充之一是方法InputStream.transferTo(OutputStream)的增加 。 顾名思义,此方法允许将字节轻松地从调用该方法的对象表示的输入流传输(复制)到提供给该方法的输出流。 或者,如该方法的Javadoc注释所述, InputStream.transferTo(OutputStream) “从此输入流中读取所有字节,并按读取顺序将这些字节写入给定的输出流中。”

关于JavaDoc的更多评论,包括以下语句的InputStream.transferTo(OutputStream)方法:

  • “此方法不会关闭任何一个流。”
  • “强烈建议在发生I / O错误时立即关闭两个流。”

处理上面显示的两个问题的最简单方法是在InputStream.transferTo(OutputStream)方法的Javadoc注释中表达的方法是在try-with-resources语句中实例化源InputStream和目标OutputStream 。 下一个代码清单中显示了一个示例。

StreamsTransfer.java :使用InputStream.transferTo(OutputStream)

package dustin.examples.iostreams;

import static java.lang.System.out;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * Demonstrate InputStream.transferTo(OutputStream) added in JDK 9.
 */
public class StreamsTransfer
{
   /**
    * Demonstrate use of InputStream.transferTo(OutputStream) using
    * FileInputStream and FileOutputStream implementations of
    * InputStream and OutputStream respectively.
    *
    * @param arguments Command-line arguments: one expected,
    *    which is the name of the input file.
    */
   public static void main(final String[] arguments)
   {
      if (arguments.length < 1)
      {
         out.println("USAGE StreamsTransfer <fileName>");
         System.exit(-1);
      }
      final String fileName = arguments[0];
      try (final InputStream is = new FileInputStream(fileName);
           final OutputStream os = new FileOutputStream(fileName + ".copy"))
      {
         is.transferTo(os);
      }
      catch (IOException exception)
      {
         out.println("Exception encountered: " + exception);
      }
   }
}

上面的代码清单中的try-with-resources语句打开两个资源( InputStreamOutputStream实例),因此确保始终关闭它们。 本示例中使用的InputStream实现是FileInputStream ,本示例中使用的OutputStream实现是FileOutputStream

尽管可以使用不同的机制 (例如,使用重载的Files.copy方法之一) 在Java中更轻松地完成上述示例中实现的文件复制,但是上面代码清单中所示的方法仅用于简单说明,并且可以可以归纳为InputStreamOutputStream任何实现。 再举一个例子,Josh Bloch在Effective Java ( 第三版 InputStream.transferTo(OutputStream)的第59项中讨论了InputStream.transferTo(OutputStream)用法,其插图使用URL.openStream()作为InputStream以及System.out作为OutputStream

执行上面的示例时,它将把提供的文件复制到另一个具有相同名称的文件,并在新文件名的末尾添加“ .copy ”。 即使两个I / O流在处理任何一个过程中发生异常,也会关闭。

在Java开发社区中,似乎普遍欢迎添加InputStream.transferTo(OutputStream)Ali Dehghani在“ Java 9的最低有效位 ”一文中讨论了这种方法。 此方法还包含在“ Java 9中的5件事变得更容易 ”一文中(还指出,现在可以在try-with-resources中有效地使用final变量,而不是像我在示例中那样明确地将它们定为final )。 Reddit / r / java子redditit包含一个有趣的讨论,标题为“ JDK 9中的新方法:InputStream.transferTo(OutputStream)”

不是所有人都喜欢在JDK 9中添加InputStream.transferTo(OutputStream) 。在“ Java 9:好的,坏的和专用的接口方法 ”一文中, Yegor BugayenkoInputStream描述为“已经过时的类”,并且写道InputStream.transferTo(OutputStream)是“年轻的OOP程序员犯的最典型的错误之一:他们使接口变大了……仅仅是因为他们需要更多的功能。” 他还指出, IOUtils.copy(InputStream,OutputStream)已通过Apache Commons提供

在JDK 9中添加InputStream.transferTo(OutputStream)方法是对标准JDK的一个很小但有时非常方便的添加,它特别易于与try-with-resources语句结合使用。

翻译自: https://www.javacodegeeks.com/2018/01/transferring-inputstream-outputstream-jdk-9.html