我惊奇地发现,今天我找不到任何简单的方法来用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);
}

当前回答

正如Javadoc所指出的那样,PipedInputStream和PipedOutputStream只能在有多个线程时使用。

另外,请注意输入流和输出流不会用ioexception包装任何线程中断…所以,你应该考虑在你的代码中加入中断策略:

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

如果您希望使用这个API复制大量数据,或者从流中复制长时间无法忍受的数据,那么这将是一个有用的补充。

其他回答

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

下面是我如何使用最简单的for循环。

private void copy(final InputStream in, final OutputStream out)
    throws IOException {
    final byte[] b = new byte[8192];
    for (int r; (r = in.read(b)) != -1;) {
        out.write(b, 0, r);
    }
}

正如Javadoc所指出的那样,PipedInputStream和PipedOutputStream只能在有多个线程时使用。

另外,请注意输入流和输出流不会用ioexception包装任何线程中断…所以,你应该考虑在你的代码中加入中断策略:

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

如果您希望使用这个API复制大量数据,或者从流中复制长时间无法忍受的数据,那么这将是一个有用的补充。

使用Guava的ByteStreams.copy():

ByteStreams.copy(inputStream, outputStream);

对于那些使用Spring框架的人来说,有一个有用的StreamUtils类:

StreamUtils.copy(in, out);

上面没有关闭流。如果你想在复制后关闭流,可以使用FileCopyUtils类:

FileCopyUtils.copy(in, out);