Chunkwise-Copy данных из InputStream в OutputStream + получение byte [] в конце - PullRequest
2 голосов
/ 15 февраля 2012

Я знаю, как скопировать кусочно из InputStream в OutputStream.

Я знаю, как получить byte[] из InputStream.

Но какобъединить их в один шаг?Есть ли OutputStream, который может быть передан по каналам и , буферизует все записанные байты, чтобы он мог возвращать байт [] в конце?

Мне нужно что-то вроде ByteArrayOutputStream, но такое, которое может бытьконвейер.(например, в FileOutputStream)

Или мне нужно что-то вроде MultiOutputStream, которое может пересылать несколько OutputStream.Решения, использующие Guava и / или Apache Commons, являются предпочтительными.:)

Ответы [ 3 ]

6 голосов
/ 15 февраля 2012

Вам, вероятно, стоит взглянуть на TeeOutputStream Apache: https://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/output/TeeOutputStream.html

1 голос
/ 17 февраля 2012

Я рассмотрел использование TeeOutputStream , но его метод close () - в методе отсутствует закрытие потока ветвления, когда закрытие основного потока вызывает исключение. Поэтому я должен сам закрыть поток ветвлений, когда возникла исключительная ситуация. Из-за концепции цепочки потоков Java это очень непрактично. Поскольку это поведение, по крайней мере, не задокументировано, я называю это ошибка .

Это на самом деле не проблема, когда я бы использовал ByteArrayOutputStream в качестве одного из потоков, к которым ветвится TeeOutputStreams. Но это только потому, что ByteArrayOutputStreams нельзя закрывать.

Вот почему я написал MultiOutputStream . Он очень похож на TeeOutputStream, но продолжает закрывать лежащие в его основе потоки, даже когда между ними возникают исключения. Кроме того, он допускает несколько потоков ветвления, а не только один.

Редактировать
Ошибка в TeeOutputStream была исправлена ​​сегодня. Он будет выпущен с Commons IO 2.2.

1 голос
/ 15 февраля 2012

Расширьте OutputStream и создайте пользовательский MultiOutputStream, обернув (подобно декоратору) два внутренних потока (ByteArrayOutputStream и FileOutputStream).Вы можете взять оба потока в качестве аргумента конструктора.Перезаписать соответствующие методы записи и записать в оба потока назначения.

например что-то вроде

  class MultiOuputStream extends OutputStream {

   private OutputStream stream1; 
   private OutputStream stream2;

   public MultiOuputStream(){
    // can throw exception, not supported
   }

   public MultiOuputStream(OutputStream stream1, OutputStream stream2){
     this.stream1 = stream1;
     this.stream2 = stream2;
   }

   @Override
   public write(byte[] bytes) throws IOException {
     stream1.write(bytes);
     stream2.write(bytes);
   }

   ...
   ...
}
...