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

当前回答

如果你正在使用Java 7,文件(在标准库中)是最好的方法:

/* You can get Path from file also: file.toPath() */
Files.copy(InputStream in, Path target)
Files.copy(Path source, OutputStream out)

编辑:当然,当你从文件中创建一个InputStream或OutputStream时,它才有用。使用file. topath()从文件中获取路径。

要写入一个现有的文件(例如用file . createtempfile()创建的文件),你需要传递REPLACE_EXISTING复制选项(否则会抛出FileAlreadyExistsException):

Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING)

其他回答

你可以使用这种方法

public static void copyStream(InputStream is, OutputStream os)
 {
     final int buffer_size=1024;
     try
     {
         byte[] bytes=new byte[buffer_size];
         for(;;)
         {
           int count=is.read(bytes, 0, buffer_size);
           if(count==-1)
               break;
           os.write(bytes, 0, count);
         }
     }
     catch(Exception ex){}
 }

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

所以,你有:

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

...在你的代码中。

你为什么要避开ioutil ?

我使用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);
    }
}

简单的函数

如果你只需要将输入流写入文件,那么你可以使用这个简单的函数:

private void copyInputStreamToFile( InputStream in, File file ) {
    try {
        OutputStream out = new FileOutputStream(file);
        byte[] buf = new byte[1024];
        int len;
        while((len=in.read(buf))>0){
            out.write(buf,0,len);
        }
        out.close();
        in.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

如果你正在使用Java 7,文件(在标准库中)是最好的方法:

/* You can get Path from file also: file.toPath() */
Files.copy(InputStream in, Path target)
Files.copy(Path source, OutputStream out)

编辑:当然,当你从文件中创建一个InputStream或OutputStream时,它才有用。使用file. topath()从文件中获取路径。

要写入一个现有的文件(例如用file . createtempfile()创建的文件),你需要传递REPLACE_EXISTING复制选项(否则会抛出FileAlreadyExistsException):

Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING)