【发布时间】:2011-06-22 15:00:27
【问题描述】:
FileInputStream in = new FileInputStream(myFile);
ByteArrayOutputStream out = new ByteArrayOutputStream();
问题:我怎样才能以一种不是我自己的字节缓冲区的手工循环的方式读取从in 到out 的所有内容?
【问题讨论】:
标签: java
FileInputStream in = new FileInputStream(myFile);
ByteArrayOutputStream out = new ByteArrayOutputStream();
问题:我怎样才能以一种不是我自己的字节缓冲区的手工循环的方式读取从in 到out 的所有内容?
【问题讨论】:
标签: java
编写一个方法来执行此操作,并从需要该功能的任何地方调用它。 Guava 已经有这方面的代码,在 ByteStreams.copy 中。我确信几乎任何其他具有“通用” IO 功能的库也有它,但 Guava 是我的第一个“首选”库。它摇滚:)
【讨论】:
ByteStreams 被注释为@Beta 这不是问题吗?
【讨论】:
在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);
}
}
【讨论】:
除了番石榴,还可以使用Apache Commons IO(旧)和Apache Commons IOUtils(评论中建议的新)。
【讨论】:
我会使用循环,而不是导入新类或将库添加到我的项目中。库函数可能也用循环实现。但这只是我个人的口味。
但是,我的问题是:你想做什么?想想“大局”,如果你想把一个文件的全部内容放到一个字节数组中,为什么不这样做呢?数组的大小是 file.length(),你不需要它动态增长,隐藏在 ByteArrayOutputStream 后面(除非你的文件是共享的,并且它的内容可以在你阅读时改变)。
另一种选择:您可以使用 FileChannel 和 ByteBuffer (java.nio) 吗?
【讨论】: