如何将一个流读入另一个流?

时间:2011-02-07 09:28:13

标签: java

FileInputStream in = new FileInputStream(myFile);
ByteArrayOutputStream out = new ByteArrayOutputStream();

问题:如何以inout的方式读取所有内容,而不是手工制作的循环使用我自己的字节缓冲区?

7 个答案:

答案 0 :(得分:32)

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

答案 1 :(得分:19)

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)

答案 2 :(得分:11)

那么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;
  }

答案 3 :(得分:11)

Java 9(及更高版本)回答:

    in.transferTo(out);

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

答案 4 :(得分: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);
    }
}

答案 5 :(得分:2)

除了Guava之外,可以使用Apache Commons IO(旧)和Apache Commons IOUtils(评论中建议的新内容)。

答案 6 :(得分:0)

我使用循环,而不是导入新类,或者向我的项目添加库。库函数也可能通过循环实现。但这只是我的个人品味。

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

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