我惊奇地发现,今天我找不到任何简单的方法来用Java将InputStream的内容写入OutputStream。显然,编写字节缓冲区代码并不难,但我怀疑我只是缺少了一些可以使我的工作更简单(并且代码更清晰)的东西。

那么,给定一个InputStream in和一个OutputStream out,是否有一种更简单的方法来编写下面的代码?

byte[] buffer = new byte[1024];
int len = in.read(buffer);
while (len != -1) {
    out.write(buffer, 0, len);
    len = in.read(buffer);
}

当前回答

我使用BufferedInputStream和BufferedOutputStream从代码中删除缓冲语义

try (OutputStream out = new BufferedOutputStream(...);
     InputStream in   = new BufferedInputStream(...))) {
  int ch;
  while ((ch = in.read()) != -1) {
    out.write(ch);
  }
}

其他回答

一个IMHO更小的代码片段(也更狭窄地作用于长度变量):

byte[] buffer = new byte[2048];
for (int n = in.read(buffer); n >= 0; n = in.read(buffer))
    out.write(buffer, 0, n);

顺便说一句,我不明白为什么更多的人不使用for循环,而是选择一段时间使用被一些人视为“糟糕”风格的赋值-测试表达式。

public static boolean copyFile(InputStream inputStream, OutputStream out) {
    byte buf[] = new byte[1024];
    int len;
    long startTime=System.currentTimeMillis();

    try {
        while ((len = inputStream.read(buf)) != -1) {
            out.write(buf, 0, len);
        }

        long endTime=System.currentTimeMillis()-startTime;
        Log.v("","Time taken to transfer all bytes is : "+endTime);
        out.close();
        inputStream.close();

    } catch (IOException e) {

        return false;
    }
    return true;
}

使用JDK方法无法更容易地做到这一点,但正如Apocalisp已经指出的那样,你不是唯一一个有这种想法的人:你可以使用Jakarta Commons IO中的IOUtils,它还有许多其他有用的东西,IMO实际上应该是JDK的一部分……

另一个可能的候选程序是Guava I/O实用程序:

http://code.google.com/p/guava-libraries/wiki/IOExplained

我认为我应该使用这些库,因为Guava在我的项目中已经非常有用,而不是为一个函数添加另一个库。

我认为最好使用一个大的缓冲区,因为大多数文件都大于1024字节。另外,检查读取字节数是否为正也是一个很好的做法。

byte[] buffer = new byte[4096];
int n;
while ((n = in.read(buffer)) > 0) {
    out.write(buffer, 0, n);
}
out.close();