2013-02-25 9 views
3

Есть ли способ построить String от ByteBuffer без предварительного считывания содержимого из буфера промежуточному byte[] или char[]?Чтение строки из ByteBuffer без двойной буферизации

АНИ похож на string constructor that takes a byte[] меня поражает, как идеал:

public String(ByteBuffer buffer, int offset, int length, Charset charset) 

... но нет такого понятия не существует.

Я нашел How to convert from ByteBuffer to Integer and String?, но использует вспомогательный массив.

I следующее лучшее, что я нашел до сих пор, это проецирование байтового буфера как CharBuffer и вызов toString(). Но это не позволяет сжимать строки с чем-то вроде UTF-8.

+0

Поддерживает ли ваш ByteBuffer метод array()? –

+0

Это карта памяти, поэтому я так не думаю. Но это все сложности, которые я хочу использовать для понимания API. –

+0

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

ответ

1

Нет такой вещи.

ByteBuffer не содержит символов. Они должны быть преобразованы в персонажей, прежде чем вы сможете сделать из них String.

Кроме того, строка должна находиться внутри памяти JVM. ByteBuffer может быть отображен или прямой, в обоих случаях он находится вне JVM.

Чтобы переместить данные в JVM и преобразовать их в символы, вы должны использовать вспомогательный массив.

+0

Да, но я не понимаю, почему String не может сделать это внутри конструктора. Зачем нужна дополнительная копия массива в API, предназначенная для высокой производительности? –

+0

Не было бы никакого преимущества в производительности, но только сложная сложность API, которая уже довольно сложна. –

2

java.lang.String является неизменным и окончательным, поэтому в конечном итоге нет выбора, кроме как в конечном итоге предоставить данные в формате, который он уже принимает. (Короткая работа с внутренними элементами с отражением, конечно ....)

Вы можете скрыть уродство за API, который использует построитель строк или что-то в этом роде, но в какой-то момент будет две копии массива в памяти, одна в построителе и один для фактической строки.

+0

В Sun JDK 1.6.0_u34, например, 'java.lang.String' имеет частный конструктор пакета следующим образом:'/* Пакет частного конструктора, который разделяет массив значений для скорости. */ String (int offset, int count, char value []) {...} 'Кажется, что API в' java.lang' может избежать второго массива ... –

+0

да, поэтому, если вы использовали отражение в переопределить доступ к этому конструктору, вы могли бы это сделать, как я упоминал :) – Affe

+0

LOL, кивает. Отражение победит цель здесь. Но пакет private означает, что другие классы в одном пакете могут использовать конструктор без каких-либо ошибок. Этот API, похоже, явно оставлен для оптимизации. Я надеялся, что они использовали прохладу, предоставленную им ... –

0

String изготовлен из char s, а не byte s. Вам понадобится набор символов , который вы используете для преобразования байтов в символы, например. UTF-8, UTF-16, ISO-8859-1, ISO-8859-5, ...

Если вы не знаете набор символов, вы не узнаете , символ которого байты представляют.

+0

Согласен. Но вот почему API моей мечты занимает Charset ... См. Мой OP. –

Смежные вопросы