Вступление
При работе со строками | в Java нам часто приходится кодировать их в определенную кодировку, такую как UTF-8 .
UTF-8 представляет собой кодировку символов переменной ширины, которая использует от одного до четырех восьмибитных байтов для представления всех допустимых кодовых точек Юникода .
Кодовая точка может представлять отдельные символы, но также иметь другие значения, например, для форматирования. “Переменная ширина” означает, что он кодирует каждую кодовую точку с разным количеством байтов (от одного до четырех), и в качестве меры экономии места обычно используемые кодовые точки представлены меньшим количеством байтов, чем те, которые используются реже.
UTF-8 использует один байт для представления кодовых точек из 0-127 , сделав первый 128 код указывает взаимно однозначную карту с символами ASCII, поэтому UTF-8 обратно совместим с ASCII.
Примечание: Java кодирует все строки в UTF-16, который использует минимум два байта для хранения кодовых точек. Зачем тогда нам нужно было бы конвертировать в UTF-8?
Не все входные данные могут быть UTF-16, или UTF-8, если на то пошло. На самом деле вы можете получить строку в кодировке ASCII, которая поддерживает не так много символов, как UTF-8. Кроме того, не все выходные данные могут обрабатывать UTF-16, поэтому имеет смысл преобразовать в более универсальный UTF-8.
Мы будем работать с несколькими Строками , которые содержат символы Юникода , с которыми вы, возможно, не сталкиваетесь ежедневно, такие как č
, β
и あ
, имитирующие ввод данных пользователем.
Давайте выпишем пару строк:
String serbianString = "Šta radiš?"; // What are you doing? String germanString = "Wie heißen Sie?"; // What's your name? String japaneseString = "よろしくお願いします"; // Pleased to meet you.
Теперь давайте воспользуемся Строкой(байт[] байт, кодировка кодировки)
конструктором строки, чтобы воссоздать эти строки, но с другой кодировкой
, имитирующей ввод ASCII , который поступил к нам в первую очередь:
String asciiSerbianString = new String(serbianString.getBytes(), StandardCharsets.US_ASCII); String asciigermanString = new String(germanString.getBytes(), StandardCharsets.US_ASCII); String asciijapaneseString = new String(japaneseString.getBytes(), StandardCharsets.US_ASCII); System.out.println(asciiSerbianString); System.out.println(asciigermanString); System.out.println(asciijapaneseString);
Как только мы создадим эти строки и закодируем их в виде символов ASCII, мы сможем их распечатать:
��ta radi��? Wie hei��en Sie? ������������������������������
В то время как первые две строки содержат всего несколько символов, которые не являются допустимыми символами ASCII, последняя строка не содержит никаких .
Чтобы избежать этой проблемы, мы можем предположить, что не все входные данные уже могут быть закодированы по нашему вкусу – и закодировать их, чтобы самим решить такие случаи. Существует несколько способов кодирования строки в UTF-8 на Java.
Кодирование строки в Java просто означает ввод определенных байтов в массив байтов, который представляет собой строку, предоставляя дополнительную информацию, которую можно использовать для ее форматирования, как только мы сформируем экземпляр String
.
Использование метода getBytes()
Класс String
, состоящий из байтов, естественно, предлагает метод getBytes ()
, который возвращает массив байтов, используемый для создания строки. Поскольку кодирование на самом деле просто манипулирует этим массивом байтов, мы можем поместить этот массив через | кодировку , чтобы сформировать его при получении данных.
По умолчанию, без указания кодировки
, байты кодируются с использованием платформы по умолчанию Кодировки
– которая может не быть UTF-8 или UTF-16. Давайте возьмем байты строки и распечатаем их:
String serbianString = "Šta radiš?"; // What are you doing? byte[] bytes = serbianString.getBytes(StandardCharsets.UTF_8); for (byte b : bytes) { System.out.print(String.format("%s ", b)); }
Это выводит:
-59 -96 116 97 32 114 97 100 105 -59 -95 63
Это кодовые точки для наших закодированных символов, и они не очень полезны для человеческих глаз. Хотя, опять же, мы можем использовать конструктор String для создания удобочитаемой строки из этой самой последовательности. Учитывая тот факт , что мы закодировали этот массив байтов в UTF_8
, мы можем продолжить и безопасно создать новую строку из этого:
String utf8String = new String(bytes); System.out.println(utf8String);
Примечание: Вместо того, чтобы кодировать их с помощью метода getBytes ()
, вы можете также кодировать байты с помощью конструктора строк:
String utf8String = new String(bytes, StandardCharsets.UTF_8);
Теперь выводится та же самая строка, с которой мы начали, но закодированная в UTF-8:
Šta radiš?
Кодируйте строку в UTF-8 с помощью стандартных наборов символов Java 7
Git Essentials
Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!
Начиная с Java 7 , мы познакомились с классом Стандартные наборы символов
, в котором доступно несколько наборов символов
, таких как US_ASCII
, ISO_8859_1
, UTF_8
и UTF-16
среди прочих.
Каждая Кодировка
имеет кодирование()
и декодирование()
метод, который принимает Буфер символов
(который реализует последовательность символов
, такую же, как Строка
). С практической точки зрения – это означает, что мы можем вставить строку в encode()
методы кодировки
.
Метод encode()
возвращает ByteBuffer
, который мы можем легко снова превратить в строку.
Ранее, когда мы использовали наш метод getBytes ()
, мы сохраняли полученные байты в массиве байтов, но при использовании класса StandardCharsets
все немного по-другому. Сначала нам нужно использовать класс ByteBuffer
для хранения наших байтов. Затем нам нужно как кодировать , так и декодировать обратно наши недавно выделенные байты. Давайте посмотрим, как это работает в коде:
String japaneseString = "よろしくお願いします"; // Pleased to meet you. ByteBuffer byteBuffer = StandardCharsets.UTF_8.encode(japaneseString); String utf8String = new String(byteBuffer.array(), StandardCharsets.UTF_8); System.out.println(utf8String);
Выполнение этого кода приводит к:
よろしくお願いします
Закодируйте строку в UTF-8 с помощью Apache Commons
Пакет кодеков Apache Commons содержит простые кодеры и декодеры для различных форматов, таких как Base64 и Шестнадцатеричный . В дополнение к этим широко используемым кодерам и декодерам, пакет кодеков также поддерживает набор утилит фонетического кодирования .
Чтобы мы могли использовать кодек Apache Commons, нам нужно добавить его в наш проект в качестве внешней зависимости.
Используя Maven, давайте добавим зависимость commons-кодек
в ваш pom.xml
файл:
commons-codec commons-codec 1.15
В качестве альтернативы, если вы используете Gradle:
compile 'commons-codec:commons-codec:1.15'
Теперь мы можем использовать служебные классы Apache Commons – и, как обычно, мы будем использовать класс StringUtils
.
Это позволяет нам преобразовывать строки в байты и из байтов, используя различные кодировки, требуемые спецификацией Java. Этот класс является нулевым и потокобезопасным, поэтому у нас есть дополнительный уровень защиты при работе со строками.
Для кодирования строки в UTF-8 с помощью класса StringUtils
Apache Common мы можем использовать метод getBytes Utf 8 ()
, который работает так же, как метод getBytes()
с указанной кодировкой
:
String germanString = "Wie heißen Sie?"; // What's your name? byte[] bytes = StringUtils.getBytesUtf8(germanString); String utf8String = StringUtils.newStringUtf8(bytes); System.out.println(utf8String);
Это приводит к:
Wie heißen Sie?
Или , вы можете использовать обычный StringUtils
класс из commons-lang3
зависимости:
org.apache.commons commons-lang3
Если вы используете Gradle:
implementation group: 'org.apache.commons', name: 'commons-lang3', version: ${version}
И теперь мы можем использовать почти тот же подход, что и с обычными строками:
String germanString = "Wie heißen Sie?"; // What's your name? byte[] bytes = StringUtils.getBytes(germanString, StandardCharsets.UTF_8); String utf8String = StringUtils.toEncodedString(bytes, StandardCharsets.UTF_8); System.out.println(utf8String);
Благодаря этому подход является потокобезопасным и нулевым:
Wie heißen Sie?
Вывод
В этом уроке мы рассмотрели как кодировать строку Java в UTF-8 . Мы рассмотрели несколько подходов – ручное создание строки с использованием getBytes()
и управление ими, класс Java 7 Стандартные наборы символов
, а также Apache Commons.