如何将一个流读入另一个流? [复制]

Posted

技术标签:

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

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

【问题讨论】:

【参考方案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) 吗?

【讨论】:

以上是关于如何将一个流读入另一个流? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

用Java复制文件的标准简洁方法?

c# - 如何将文件写入内存流,压缩其中三个内存流,然后将其放入另一个内存流?

Spring Webflow:如何在转换期间将属性从一个流传递到另一个流?

JAVA IO流复制文件内容

WPF中 如何将图片文件夹下的image图片转化成二进制byte[] 文件

IO流的文件复制