Как поместить содержимое ByteBuffer в OutputStream?

Мне нужно поместить содержимое java.nio.ByteBuffer в java.io.OutputStream. (хотелось бы, чтобы вместо этого было Channel, но у меня его нет) Как лучше всего это сделать?

Я не могу использовать метод array() ByteBuffer, поскольку он может быть буфером только для чтения.

Я также могу чередовать записи в OutputStream между использованием этого ByteBuffer и наличием обычного массива byte[], который я могу напрямую использовать OutputStream.write().


person Jason S    schedule 23.02.2009    source источник


Ответы (1)


Посмотрите на Channels.newChannel(OutputStream). Это даст вам канал с учетом OutputStream. С адаптером WritableByteChannel вы можете предоставить ByteBuffer, который запишет его в OutputStream.

public void writeBuffer(ByteBuffer buffer, OutputStream stream) {
   WritableByteChannel channel = Channels.newChannel(stream);

   channel.write(buffer);
}

Это должно сработать!

person ng.    schedule 23.02.2009
comment
если я сохраняю канал, а также поток, могу ли я смешивать вызовы с обоими? - person Jason S; 24.02.2009
comment
Да, конечно можно, каждый раз снижает стоимость создания канала :) - person ng.; 24.02.2009
comment
Обратите внимание, что этот подход включает копирование из ByteBuffer во временный массив, который затем записывается в OutputStream. Если важна производительность, возможно, вам придется провести небольшой рефакторинг, чтобы избежать ненужных блочных копий. - person Trevor Robinson; 15.08.2012
comment
@ Trevor-Robinson, не могли бы вы расширить этот комментарий? Почему речь идет о копии? Как этого избежать? - person Frederik; 13.02.2015
comment
@Frederik, сам OutputStream принимает только массивы байтов, а поскольку ByteBuffer.array() может не поддерживаться, копирование - единственный способ вообще. В качестве особого случая реализация Oracle/OpenJDK Channels.newChannel действительно проверяет, является ли поток (точно) FileOutputStream, имеющим реальный родной канал; в противном случае он возвращает адаптер (Channels.WritableByteChannelImpl), который копирует из буфера в массив фрагментами размером до 8 КБ. Единственный способ избежать этого — использовать каналы повсюду. Вы должны спроектировать NIO, чтобы получить преимущества производительности. - person Trevor Robinson; 14.02.2015