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

当前回答

我使用ByteStreamKt。copyTo(src, dst, buffer.length)方法

这是我的代码

public static void replaceCurrentDb(Context context, Uri newDbUri) {
    try {
        File currentDb = context.getDatabasePath(DATABASE_NAME);
        if (currentDb.exists()) {
            InputStream src = context.getContentResolver().openInputStream(newDbUri);
            FileOutputStream dst = new FileOutputStream(currentDb);
            final byte[] buffer = new byte[8 * 1024];
            ByteStreamsKt.copyTo(src, dst, buffer.length);
            src.close();
            dst.close();
            Toast.makeText(context, "SUCCESS! Your selected file is set as current menu.", Toast.LENGTH_LONG).show();
        }
        else
            Log.e("DOWNLOAD:::: Database", " fail, database not found");
    }
    catch (IOException e) {
        Toast.makeText(context, "Data Download FAIL.", Toast.LENGTH_LONG).show();
        Log.e("DOWNLOAD FAIL!!!", "fail, reason:", e);
    }
}

其他回答

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

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

Java 9

自Java 9以来,InputStream提供了一个名为transferTo的方法,具有以下签名:

public long transferTo(OutputStream out) throws IOException

如文档所述,transferTo将:

Reads all bytes from this input stream and writes the bytes to the given output stream in the order that they are read. On return, this input stream will be at end of stream. This method does not close either stream. This method may block indefinitely reading from the input stream, or writing to the output stream. The behavior for the case where the input and/or output stream is asynchronously closed, or the thread interrupted during the transfer, is highly input and output stream specific, and therefore not specified

因此,为了将Java InputStream的内容写入到OutputStream,你可以这样写:

input.transferTo(output);

使用Commons Net的Util类:

import org.apache.commons.net.io.Util;
...
Util.copyStream(in, out);

试试Cactoos:

new LengthOf(new TeeInput(input, output)).value();

更多详情请访问:http://www.yegor256.com/2017/06/22/object-oriented-input-output-in-cactoos.html

正如WMR提到的,来自Apache的ioutils有一个叫做copy(InputStream,OutputStream)的方法,它所做的正是您所寻找的。

所以,你有:

InputStream in;
OutputStream out;
IOUtils.copy(in,out);
in.close();
out.close();

...在你的代码中。

你为什么要避开ioutil ?