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

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

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

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

在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)

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

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

 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 9(及更高版本)回答:

  in.transferTo(out); 

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

作为Guava的替代,可以使用Apache Commons IO (旧版)和Apache Commons IOUtils (评论中建议的新版本)。

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

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

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