Перевод byte в string java

Преобразование из String в массив байтов и обратно

Написал на Java следующую последовательность действий:

Получаю из строки с кириллицей массив байтов

Получается следующий массив:

[-19, -18, -30, -32, -1, 32, -15, -14, -16, -18, -22, -32]

Передаю его на вход классу ByteArrayOutputStream

Выполняю обратное преобразование из массива байтов в строку

Программа выводит в консоль текст новая строка

Вопрос: так как кириллица в юникоде имеет кодепойнты, превышающие 1 тысячу (кодепойнт буквы А , к примеру, равен 1040), а байт в Java может принимать значения от -128 до 127, следовательно при попытке преобразовать строку в массив типа byte должна происходить потеря информации, как следствие — при вызове метода toString() строка должна восстановиться некорректно. Но этого не произошло. В чем тут причина?

1 ответ 1

Это не юникод. String.getBytes() использует кодировку по-умолчанию платформы:

Encodes this String into a sequence of bytes using the platform’s default charset, storing the result into a new byte array.

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

Для получения байтов в юникоде, задайте кодировку явно:

Получится больше 12 байтов.

Обновление по вопросам в комментарии:

Разве UTF-8 выдает байты, эквивалентные юникодовскому представлению?

У юникода бывают разные представления. UTF-8 — одно из них.

Я знаю, что char выдает кодепойнты юникода. Если вывести System.out.println((byte)’н’), то это будет равно 61.

Здесь можно посмотреть как строчная кириллическая «н» представляется в разных кодировках: https://unicode-table.com/en/043D/

UTF-8:
Десятичное значение: 53437
Байты: 208 189

UTF-16BE:
Десятичное значение: 1085
Байты: 4 61

Для char в Java, согласно спецификации (§3.1 Unicode) используется кодировка UTF-16. Это тоже двухбайтовая кодировка. Соответственно, когда Вы приводите char к byte Вы получаете младший байт в этой кодировке.

Получить байты в «UTF-16BE» можно так:

Если вывести байты, как Вы предложили byte[] bytes=»новая строка».getBytes(«UTF-8»), то там первый байт равен -48, а не 61.

Кодировка UTF-8, как указано ранее беззнаковые (от 0 до 255) байты: 208 и 189. Знаковые байты, соответственно, -48 и -67.

Источник

How to convert byte[] array to String in Java

In Java, we can use new String(bytes, StandardCharsets.UTF_8) to convert a byte[] to a String.

For text or character data, we use new String(bytes, StandardCharsets.UTF_8) to convert a byte[] to a String . However, for cases that byte[] is holding the binary data like the image or other non-text data, the best practice is to convert the byte[] into a Base64 encoded String.

  1. For text data byte[] , we use new String(bytes, StandardCharsets.UTF_8) , UTF-8 for character encoding.
  2. For binary data byte[] , we use the Base64 binary encoding.

1. Convert byte[] to String (text data)

The below example converts a string to a byte array and vice versa.

2. Convert byte[] to String (binary data)

The below example convert an image phone.png into a byte[] , and uses the Java 8 Base64 class to convert the byte[] to a Base64 encoded String. Later, we convert the Base64 encoded string back to the original byte[] and save it into another image named phone2.png .

Download Source Code

References

mkyong

Thanks, article is update with this
new String(bytes, StandardCharsets.UTF_8)

Thank You. This Helped.

The value returned by array.toString() is *not* the binary representation of the array’s elements. It is the default toString() method implemented by Object, and it returns the address of the object in memory. See here: http://stackoverflow.com/a/36994589/712526

Incidentally, this is why String.valueOf(bytes) does not work, either.

Thanks, article is updated with new String()

Please correct me if i am wrong. Just see ur article but it seems its mostly misguided.

“Simple toString() function like following code is not working property. It will not display the original text but byte value.”
toString is working properly if you see the documentation you will know. So lets c the behavior of this method

System.out.println(“Text [Byte Format] : ” + bytes);
System.out.println(“Text [Byte Format] : ” + bytes.toString());

Text [Byte Format] : [B@187aeca
Text [Byte Format] : [B@187aeca

The both above lines are same if you use bytes in Print method it will automatically calls toString()
method on this object before concatenation.

Below line is not printing the bytes values but that is the object name and System.identityHashCode() separated by the ‘@’ character. What the identity hash code represents is implementation-specific. It often is the initial memory address of the object, but the object can be moved in memory by the VM over time. So (briefly) you can’t rely on it being anything.

System.out.println(“Text [Byte Format] : ” + bytes);

At this point you are creating new String by using bytes values not byte Object location.
So the result is right.

Источник

[Перевод] Java Best Practices. Преобразование Char в Byte и обратно

Сайт 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% ускорения по сравнению с классическими подходами.

Источник

Поделиться с друзьями
admin
Оцените автора
( Пока оценок нет )
Как переводится?
Adblock
detector