2013-10-10 3 views
6

Я наткнулся на этот запрос: Create a ByteBuf in Netty 4.0 о преобразовании из байта [] в ByteBuf и ByteBuffer в ByteBuf. Мне было интересно узнать о преобразовании в другую сторону:Эффективный способ конвертировать io.netty.buffer.ByteBuf в java.nio.ByteBuffer

io.netty.buffer.ByteBuf к java.nio.ByteBuffer

и как сделать это эффективно, с минимальным/не копирования? Я сделал некоторое чтение и с некоторыми проб и ошибок я нашел это неэффективный способ преобразования его (с двумя копиями):

Мой вопрос, можем ли мы избежать одну или обе копии и сделать внутренний буфер ByteBuffer для использования внутреннего буфера ByteBuf.

Спасибо!

ответ

3

Чтобы избежать второго копирования, вы можете хотя бы использовать ByteBuffer.wrap().

+0

Можем ли мы избежать первой копии? – Corehacker

+2

Кажется, ответ Дэва ниже поможет устранить это. – Kayaman

8

Вы должны иметь возможность использовать ByteBuf.nioBuffers(). Что вернет представление ByteBuf как массив объектов ByteBuffer.

В большинстве случаев этот массив будет иметь только один элемент, но в некоторых из более сложных реализаций ByteBuf может быть несколько базовых объектов ByteBuffer и ByteBuf.nioBuffers() может возвратить их как есть вместо объединения их бы призыв к ByteBuf.nioBuffer() ,

Вы можете сказать заранее, что длина массива будет с помощью ByteBuf.nioBufferCount()

+0

Это не касается, когда он поддерживается байтом [] – ruckc

+0

@Dev, когда вы используете 'ByteBuf.nioBuffers()' или 'ByteBuf.nioBuffer()' для возврата представления ByteBuf в виде массива объектов ByteBuffer или один объект ByteBuffer, что произойдет, если вы хотите освободить ByteBuf? По-видимому, проблемы возникают с созданным объектом ByteBuffer, когда это происходит, когда ByteBuf и ByteBuffer делят базовые данные. – mcarlin

0

Не особенно эффективной, но делает трюк:

public static ByteBuffer toNioBuffer(ByteBuf buffer) { 
    if (buffer.isDirect()) { 
     return buffer.nioBuffer(); 
    } 
    final byte[] bytes = new byte[buffer.readableBytes()]; 
    buffer.getBytes(buffer.readerIndex(), bytes); 
    return ByteBuffer.wrap(bytes); 
}