Easy way to write contents of a Java InputStream t

2018-12-31 06:01发布

I was surprised to find today that I couldn't track down any simple way to write the contents of an InputStream to an OutputStream in Java. Obviously, the byte buffer code isn't difficult to write, but I suspect I'm just missing something which would make my life easier (and the code clearer).

So, given an InputStream in and an OutputStream out, is there a simpler way to write the following?

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

标签: java io stream
20条回答
梦醉为红颜
2楼-- · 2018-12-31 06:31

Using Guava's ByteStreams.copy():

ByteStreams.copy(inputStream, outputStream);
查看更多
明月照影归
3楼-- · 2018-12-31 06:32

Using Java7 and try-with-resources, comes with a simplified and readable version.

    try(InputStream inputStream     =   new FileInputStream("C:\\mov.mp4");
        OutputStream outputStream   =   new FileOutputStream("D:\\mov.mp4")){

        byte[] buffer    =   new byte[10*1024];

        for (int length; (length = inputStream.read(buffer)) != -1; ){
            outputStream.write(buffer, 0, length);
        }

    }catch (FileNotFoundException exception){
        exception.printStackTrace();
    }catch (IOException ioException){
        ioException.printStackTrace();
    }
查看更多
千与千寻千般痛.
4楼-- · 2018-12-31 06:32

A IMHO more minimal snippet (that also more narrowly scopes the length variable):

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

As a side note, I don't understand why more people don't use a for loop, instead opting for a while with an assign-and-test expression that is regarded by some as "poor" style.

查看更多
深知你不懂我心
5楼-- · 2018-12-31 06:34

If you are using Java 7, Files (in the standard library) is the best approach:

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

Edit: Of course it's just useful when you create one of InputStream or OutputStream from file. Use file.toPath() to get path from file.

To write into an existing file (e.g. one created with File.createTempFile()), you'll need to pass the REPLACE_EXISTING copy option (otherwise FileAlreadyExistsException is thrown):

Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING)
查看更多
呛了眼睛熬了心
6楼-- · 2018-12-31 06:34

Try Cactoos:

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

More details here: http://www.yegor256.com/2017/06/22/object-oriented-input-output-in-cactoos.html

查看更多
旧人旧事旧时光
7楼-- · 2018-12-31 06:35

Java 9

Since Java 9, InputStream provides a method called transferTo with the following signature:

public long transferTo(OutputStream out) throws IOException

As the documentation states, transferTo will:

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

So in order to write contents of a Java InputStream to an OutputStream, you can write:

input.transferTo(output);
查看更多
登录 后发表回答