Массив байт в строку java

Массив байт в строку java

Сайт Java Code Geeks изредка публикует посты в серии Java Best Practices — проверенные на production решения. Получив разрешение от автора, перевёл один из постов. Дальше — больше.

Продолжая серию статей о некоторых аспектах программирования на Java, мы коснёмся сегодня производительности String, особенно момент преобразования character в байт-последовательность и обратно в том случае, когда используется кодировка по умолчанию. В заключение мы приложим сравнение производительности между неклассическими и классическими подходами для преобразования символов в байт-последовательность и обратно.

Все изыскания базируются на проблемах в разработке крайне эффективных систем для задач в области телекоммуникации (ultra high performance production systems for the telecommunication industry).

Перед каждой из частей статьи очень рекомендуем ознакомиться с Java API для дополнительной информации и примеров кода.

Эксперименты проводились на Sony Vaio со следующими характеристиками:
ОС: openSUSE 11.1 (x86_64)
Процессор (CPU): Intel® Core(TM)2 Duo CPU T6670 @ 2.20GHz
Частота: 1,200.00 MHz
ОЗУ (RAM): 2.8 GB
Java: OpenJDK 1.6.0_0 64-Bit

Со следующими параметрами:
Одновременно тредов: 1
Количество итераций эксперимента: 1000000
Всего тестов: 100

Преобразование Char в Byte и обратно:

Задача преобразования Char в Byte и обратно широко распространена в области коммуникаций, где программист обязан обрабатывать байтовые последовательности, сериализовать String-и, реализовывать протоколы и т.д.
Для этого в Java существует набор инструментов.

Метод «getBytes(charsetName)» класса String, наверное, один из популярнейших инструментов для преобразования String в его байтовый эквивалент. Параметр charsetName указывает на кодировку String, в случае отсутствия оного метод кодирует String в последовательность байт используя стоящую в ОС по умолчанию кодировку.

Ещё одним классическим подходом к преобразованию массива символов в его байтовый эквивалент является использование класса ByteBuffer из пакета NIO (New Input Output).

Читайте также:  Как узнать где находится человек по сотовому

Оба подхода популярны и, безусловно, достаточно просты в использовании, однако испытывают серьёзные проблемы с производительностью по сравнению с более специфическими методами. Помните: мы не конвертируем из одной кодировки в другую, для этого вы должны придерживаться «классических» подходов с использованием либо «String.getBytes (charsetName)» либо возможностей пакета NIO.

В случае ASCII мы имеем следующий код:

Массив b создаётся путём кастинга (casting) значения каждого символа в его байтовый эквивалент, при этом учитывая ASCII-диапазон (0-127) символов, каждый из которых занимает один байт.

Массив b можно преобразовать обратно в строку с помощью конструктора «new String(byte[])»:

Для кодировки по умолчанию мы можем использовать следующий код:

Каждый символ в Java занимает 2 байта, для преобразования строки в байтовый эквивалент нужно перевести каждый символ строки в его двухбайтовый эквивалент.

И обратно в строку:

Мы восстанавливаем каждый символ строки из его двухбайтового эквивалента и затем, опять же с помощью конструктора String(char[]), создаём новый объект.

Примеры использования возможностей пакета NIO для наших задач:

А теперь, как и обещали, графики.

String в byte array:

Ось абсцисс — количество тестов, ординат — количество операций в секунду для каждого теста. Что выше — то быстрее. Как и ожидалось, «String.getBytes()» и «stringToBytesUTFNIO(String)» отработали куда хуже «stringToBytesASCII(String)» и «stringToBytesUTFCustom(String)». Наши реализации, как можно увидеть, добились почти 30% увеличения количества операций в секунду.

Byte array в String:

Результаты опять же радуют. Наши собственные методы добились 15% увеличения количества операций в секунду по сравнению с «new String(byte[])» и 30% увеличения количества операций в секунду по сравнению с «bytesToStringUTFNIO(byte[])».

В качестве вывода: в том случае, если вам необходимо преобразовать байтовую последовательность в строку или обратно, при этом не требуется менять кодировки, вы можете получить замечательный выигрыш в производительности с помощью самописных методов. В итоге, наши методы добились в общем 45% ускорения по сравнению с классическими подходами.

Читайте также:  Как восстановить удаленную программу в виндовс 8

Мне нужно преобразовать массив байтов в строку в Android, но мой массив байтов содержит отрицательные значения.

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

Что я могу сделать для правильного преобразования? Код, который я использую для преобразования, выглядит следующим образом:

Я застрял в этой проблеме.

Ваш массив байтов должен иметь некоторую кодировку. Кодировка не может быть ASCII, если у вас есть отрицательные значения. Как только вы это выясните, вы можете преобразовать набор байтов в строку, используя:

Существует множество кодировок, которые вы можете использовать, посмотрите класс Charset в Sun javadocs.

"Правильное преобразование" между byte[] и String — это явно указать кодировку, которую вы хотите использовать. Если вы начинаете с byte[] и на самом деле не содержат текстовых данных, нет "правильного преобразования". String предназначены для текста, byte[] для двоичных данных, и единственно разумная вещь, которую нужно сделать, — избегать конвертации между ними, если только вам это не нужно.

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

Проблема с корнем (я думаю), что вы невольно используете набор символов, для которого:

в некоторых случаях. UTF-8 является примером такого набора символов. В частности, некоторые последовательности байтов не являются допустимыми кодировками в UTF-8. Если декодер UTF-8 встречает одну из этих последовательностей, он может отбросить оскорбительные байты или декодировать их как кодовый номер Юникода для "нет такого символа". Естественно, когда вы затем пытаетесь кодировать символы как байты, результат будет другим.

November 2018

221k раз

Я пишу веб — приложение в Google App Engine. Это позволяет людям в основном редактировать HTML код , который получает хранится в виде .html файла в Blobstore.

Читайте также:  Группа строителей в роблокс

Я использую fetchData для возврата byte[] всех символов в файле. Я пытаюсь напечатать к HTML для того , чтобы пользователю редактировать HTML — код. Все прекрасно работает!

Вот моя единственная проблема сейчас:

Массив имеет некоторые проблемы при преобразовании обратно в строку. Умные цитаты и пару символов выходят глядя в стиле фанк. (? S или японские символы и т.д.) В частности, это несколько байт я вижу, что есть отрицательные значения, которые вызывают проблемы.

Умные цитаты возвращаются , как -108 и -109 в массиве байтов. Почему это и как я могу расшифровать отрицательные байты , чтобы показать правильную кодировку символов?

Ссылка на основную публикацию
Люстра с пультом управления светодиодная инструкция
Идея установить и подключить люстру с пультом замечательна тем, что хозяева квартиры получают возможность управлять освещением, не привязываясь к выключателю....
Линза для лазерного диода
Асферические линзы используются для коррекции сферических аберраций. Вместо применения сложных линз такие аберрации могут быть снижены до минимума при использовании...
Линукс для нетбука acer aspire one
Автор — Андрес Брачо (Andrés Bracho) Я не технарь, не компьютерщик и не программист. Я всего лишь среднестатис-тический пользователь, кото-рый...
Ля рош позе скидки
12 актуальных предложений март 2020 Сэкономьте 10% с промокодом при покупке более 3000 рублей Приобретите в интернет-магазине La Roche Posay...
Adblock detector