【问题标题】:How to read one stream into another? [duplicate]如何将一个流读入另一个流? [复制]
【发布时间】:2011-06-22 15:00:27
【问题描述】:
FileInputStream in = new FileInputStream(myFile);
ByteArrayOutputStream out = new ByteArrayOutputStream();

问题:我怎样才能以一种不是我自己的字节缓冲区的手工循环的方式读取从inout 的所有内容?

【问题讨论】:

    标签: java


    【解决方案1】:

    编写一个方法来执行此操作,并从需要该功能的任何地方调用它。 Guava 已经有这方面的代码,在 ByteStreams.copy 中。我确信几乎任何其他具有“通用” IO 功能的库也有它,但 Guava 是我的第一个“首选”库。它摇滚:)

    【讨论】:

    • ByteStreams 被注释为@Beta 这不是问题吗?
    • @gabuzo:这取决于你厌恶风险的程度。我怀疑该方法调用不太可能发生变化,并且我确信实现是好的。
    • 即使它发生变化或消失,您也只有在升级时不得不修复它的风险。该方法很简单,并且源代码可用(甚至作为 subversion repo)。
    【解决方案2】:

    Java 9(及更高版本)答案 (docs):

    in.transferTo(out);
    

    似乎他们终于意识到这个功能是如此普遍需要,最好内置它。该方法返回复制的字节数以防您需要知道。

    【讨论】:

      【解决方案3】:

      Apache Commons / IO,您可以使用IOUtils.copy(in, out)

      InputStream in = new FileInputStream(myFile);
      OutputStream out = new ByteArrayOutputStream();
      IOUtils.copy(in, out);
      

      但我同意 Jon Skeet 的观点,我宁愿使用 Guava 的 ByteStreams.copy(in, out)

      【讨论】:

        【解决方案4】:

        那么 Guava 的 ByteStreams.copy(in, out) 做了什么:

          private static final int BUF_SIZE = 0x1000; // 4K
        
          public static long copy(InputStream from, OutputStream to)
              throws IOException {
            checkNotNull(from);
            checkNotNull(to);
            byte[] buf = new byte[BUF_SIZE];
            long total = 0;
            while (true) {
              int r = from.read(buf);
              if (r == -1) {
                break;
              }
              to.write(buf, 0, r);
              total += r;
            }
            return total;
          }
        

        【讨论】:

          【解决方案5】:

          在我的项目中我使用了这种方法:

          private static void copyData(InputStream in, OutputStream out) throws Exception {
              byte[] buffer = new byte[8 * 1024];
              int len;
              while ((len = in.read(buffer)) > 0) {
                  out.write(buffer, 0, len);
              }
          }
          

          【讨论】:

          • 如果您解释为什么您的代码不同以及它如何解决问题,这可能对其他人有所帮助
          • 简洁的代码,不使用库。
          • 只是简短的代码,没有任何依赖,纯java
          【解决方案6】:

          除了番石榴,还可以使用Apache Commons IO(旧)和Apache Commons IOUtils(评论中建议的新)。

          【讨论】:

          • 已弃用。使用 IOUtils。将在 2.0 中删除。方法重命名为 IOUtils.write() 或 IOUtils.copy()
          • @Sean Patrick Floyd Thanx -- 已更新答案。
          【解决方案7】:

          我会使用循环,而不是导入新类或将库添加到我的项目中。库函数可能也用循环实现。但这只是我个人的口味。

          但是,我的问题是:你想做什么?想想“大局”,如果你想把一个文件的全部内容放到一个字节数组中,为什么不这样做呢?数组的大小是 file.length(),你不需要它动态增长,隐藏在 ByteArrayOutputStream 后面(除非你的文件是共享的,并且它的内容可以在你阅读时改变)。

          另一种选择:您可以使用 FileChannel 和 ByteBuffer (java.nio) 吗?

          【讨论】:

            猜你喜欢
            • 2010-09-18
            • 2011-04-13
            • 1970-01-01
            • 2010-09-12
            • 2011-01-06
            • 2017-05-27
            • 1970-01-01
            • 2017-08-27
            相关资源
            最近更新 更多