2013-03-01 9 views
0

Знаете ли вы о какой-либо реализации java.nio.ByteBuffer, которая обертывает массив экземпляров ByteBuffer, делая их похожими на один экземпляр без копирования байтов в новый буфер?ByteBuffer views

+1

'ByteBuffer' (' Buffer') является исправить размер. Невозможно сделать что-то вроде «конкатенации». Что вы действительно хотите сделать? – shuangwhywhy

+0

Я оптимизирую код низкого уровня, который опирается на ByteBuffers, и было бы полезно уменьшить количество копий байтов, которые происходят. Естественно, что копирование байтов между байтовыми буферами прост, но, как обнаружили рамки nio; делая это для большого объема байтов снова и снова, накапливается. –

+0

Почему бы не создать большой 'ByteBuffer' сразу? Или просто используйте массивы. – shuangwhywhy

ответ

3

В java.nio реализации не существует, но практически все каналы реализуют GatheringByteChannel и ScatteringByteChannel, которые могут напрямую считывать и записывать в массивы ByteBuffers.

GatheringByteChannel:

long write(ByteBuffer[] srcs)

Записывает последовательность байтов к этому каналу от заданных буферов.

и ScatteringByteChannel:

длиной read(ByteBuffer[] dsts)

Считывает последовательность байтов от этого канала в данный буфер.

Есть также частичные версии вышеуказанных методов, см. Ссылки выше.

Точка NIO должна иметь как можно меньше накладных расходов, и этот способ выполнения (в отличие от того, что отдельный объект обертывает буферы) не несет дополнительных накладных расходов, чем простой массив. Я думаю, что ваш - это предполагаемый прецедент для этого и их реализация.

+0

Ближайшим, что я знаю, является класс, называемый Bytes внутри Netty, но, к сожалению, они не распространяют ByteBuffer для его достижения. Канал - это неправильный класс для меня, я хочу передать это через библиотеку, которая требует ByteBuffer (а не Channel). Я уже решил это, скопировав байты, но по мере того, как через эту систему будет проходить много байтов, тем меньше копирует бит, что происходит лучше. Спасибо за ваши мысли. –

+1

Почему бы вам не разбить библиотеку и не расширять методы, чтобы позволить массиву 'ByteBuffer' вместо одного байтового буфера? Я предполагаю, что основные «каналы», которые читают и пишут, будут поддерживать описанные выше операции, и вам не придется менять более нескольких строк, чтобы заставить его работать. –

+0

Это интересная идея, спасибо. Я не думал об этом. Мой инстинкт кишки заключается в том, что для этого потребуется больше времени, чем просто обернуть ByteBuffer. Но я подниму его и посмотрю, куда он ведет. Если у них есть базовый код, как вы ожидаете, мне просто повезет. –

1

В стандартном Java API нет ни одного. Grizzly NIO рамка имеет CompositeBuffer, но использует его собственный буфер обетрки:

import org.glassfish.grizzly.Buffer; 
import org.glassfish.grizzly.memory.BuffersBuffer; 
import org.glassfish.grizzly.memory.CompositeBuffer;  

.... 

ByteBuffer byteBuffer = ....; 
HeapMemoryManager mm = new HeapMemoryManager(); 
CompositeBuffer buffer = BuffersBuffer.create(); 
Buffer b = mm.wrap(byteBuffer); 
buffer.append(b);