Простой способ записать содержимое Java InputStream в OutputStream - PullRequest
404 голосов
/ 04 сентября 2008

Сегодня я с удивлением обнаружил, что не могу отыскать простой способ записать содержимое InputStream в OutputStream в Java. Очевидно, что код байтового буфера не сложно написать, но я подозреваю, что мне просто не хватает чего-то, что сделало бы мою жизнь проще (и код понятнее).

Итак, при 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);
}

Ответы [ 21 ]

6 голосов
/ 21 августа 2015

Использование Java7 и try-with-resources поставляется с упрощенной и читаемой версией.

    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 голосов
/ 12 ноября 2013

Используйте класс Util Commons Net:

import org.apache.commons.net.io.Util;
...
Util.copyStream(in, out);
4 голосов
/ 22 августа 2016

Вот как я работаю с самым простым циклом 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);
    }
}
3 голосов
/ 10 декабря 2015

ИМХО более минимальный фрагмент (который также более узко ограничивает переменную длины):

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

В качестве примечания, я не понимаю, почему все больше людей не используют цикл for, вместо этого выбирая while с выражением присваивания и тестирования, которое некоторые считают «плохим» стиль.

2 голосов
/ 13 сентября 2013

Я думаю, что лучше использовать большой буфер, потому что большинство файлов больше 1024 байтов. Также рекомендуется проверять положительное число прочитанных байтов.

byte[] buffer = new byte[4096];
int n;
while ((n = in.read(buffer)) > 0) {
    out.write(buffer, 0, n);
}
out.close();
0 голосов
/ 11 декабря 2012

Другим возможным кандидатом являются утилиты ввода / вывода Guava:

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

Я думал, что буду использовать их, поскольку Guava уже очень полезен в моем проекте, вместо того, чтобы добавлять еще одну библиотеку для одной функции.

0 голосов
/ 02 апреля 2015
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;
}
0 голосов
/ 04 сентября 2008

PipedInputStream и PipedOutputStream могут быть полезны, так как вы можете подключить одно к другому.

0 голосов
/ 21 сентября 2017

Попробуйте Cactoos :

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

Подробнее здесь: http://www.yegor256.com/2017/06/22/object-oriented-input-output-in-cactoos.html

0 голосов
/ 20 января 2019

Я использую BufferedInputStream и BufferedOutputStream для удаления семантики буферизации из кода

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