JavaRush/Курсы/Java Multithreading/Character, кодировки

Character, кодировки

Открыта

— Привет, Амиго!

Сейчас будет еще одна интересная тема – кодировки.

Возможно, ты где-то уже слышал, что у каждого символа есть код (число). Именно поэтому тип char считается не только символьным, но и числовым типом.

Например код символа А английского алфавита – 65. B – 66, C – 67и так далее. Свои коды есть у больших букв и у маленьких, у русских букв, у китайских (ага, много, много кодов), у цифр, у различных символов – словом практически у всего, что можно назвать символом.

— Т.е. каждой букве или каждому символу соответствует какое-то число?

— Да, именно так.

Символ можно преобразовать в число, а число в символ. Java вообще практически не видит разницы между ними:

char c = 'A'; //код(число) буквы А – 65
c++; //Теперь с содержит число 66 – код буквы B

— Интересно.

— Так вот, кодировкой называется набор символов и соответствующий им набор кодов. Только таких кодировок придумали не одну, а достаточно много. А потом появилась универсальная – Unicode.

Хотя, сколько бы универсальных стандартов не придумали, от старых никто отказываться не спешит. И все получается прямо как на этой картинке:

Character, кодировки - 1

Вот представь, что Вася и Коля захотели самостоятельно придумать кодировки.

Вот кодировка Васи:
Character, кодировки - 2

А вот кодировка Коли:
Character, кодировки - 3

Они даже используют одни и те же символы, но коды у этих символов разные.

И вот когда строку «ABC-123» в кодировке Васи записывают в файл, туда пишется набор байт:
Character, кодировки - 4

А теперь этот файл хочет прочитать другая программа, которая использует кодировку Коли:

Вот что она прочитает«345-IJK»

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

— А как их угадывать?

— Это отдельная тема. Но я хочу тебе рассказать, как работать с кодировками. Как ты уже знаешь, размер типа char в Java – два байта. И строки в Java имеют формат Unicode.

Но Java позволяет преобразовать строку в набор байт любой известной ей кодировки. Для этого есть специальные методы у класса String(!). Также в Java есть специальный класс Charset, который описывает конкретную кодировку.

1) Как получить список всех кодировок, с которыми Java может работать?

Для этого есть специальный статический метод availableCharsets. Этот метод возвращает набор пар (имя кодировки, объект описывающий кодировку)

SortedMap<String,Charset> charsets = Charset.availableCharsets();

У каждой кодировки есть уникальное имя, вот некоторые из них: UTF-8, UTF-16, Windows-1251, KOI8-R,…

2) Как получить текущую активную кодировку (Unicode)?

Для этого есть специальный метод defaultCharset

Charset currentCharset = Charset.defaultCharset();

3) Как преобразовать строку в определенную кодировку?

В Java на основе строки можно создать массив байт в любой известной Java кодировке:

Метод Пример
byte[] getBytes()
String s = "Good news everyone!";
byte[] buffer = s.getBytes()
byte[] getBytes(Charset charset)
String s = "Good news everyone!";
Charset koi8 = Charset.forName("KOI8-R");
byte[] buffer = s.getBytes(koi8);
byte[] getBytes(String charsetName)
String s = "Good news everyone!";
byte[] buffer = s.getBytes("Windows-1251")

4) А как преобразовать набор байт, которые я прочитал из файла в строку, если я знаю в какой кодировке они были в файле?

Тут все еще проще – у класса String есть специальный конструктор:

Метод Пример
String(byte bytes[])
byte[] buffer = new byte[1000];
inputStream.read(buffer);

String s = new String(buffer);
String(byte bytes[], Charset charset)
byte[] buffer = new byte[1000];
inputStream.read(buffer);

Charset koi8 = Charset.forName("KOI8-R");
String s = new String(buffer, koi8);
String(byte bytes[], String charsetName)
byte[] buffer = new byte[1000];
inputStream.read(buffer);

String s = new String(buffer, "Windows-1251");

5) А как преобразовать набор байт из одной кодировки в другую?

Есть много способов. Вот тебе один из самых простых:

Charset koi8 = Charset.forName("KOI8-R");
Charset windows1251 = Charset.forName("Windows-1251");

byte[] buffer = new byte[1000];
inputStream.read(buffer);
String s = new String(buffer, koi8);
buffer = s.getBytes(windows1251);
outputStream.write(buffer);

— Я так и думал. Спасибо за интересную лекцию, Риша.

Комментарии (84)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Real User
Уровень 40
22 мая, 09:26
Было бы полезно в мультитрейдинге, заниматься мультитрейдингом. Оптья какая-то херота
Никита
Уровень 1
3 октября 2025, 17:17
было бы полезно оставить пару слов про утилитарный класс java.nio.charset.StandardCharsets
No Name
Уровень 22
23 ноября 2024, 15:59
+ лекция в копилке
Максим Li Backend Developer
19 мая 2024, 16:20
19.05.2024
Ислам
Уровень 33
17 марта 2024, 07:14
Nice
Dmitry Shaburov
Уровень 33
7 марта 2024, 07:51
07.03.2024
Denis Odesskiy Full Stack Developer
18 ноября 2023, 20:44
Приходит программист к окулисту. Тот его усаживает напротив таблицы, берёт указку и говорит: -Читайте! -"БНОПНЯ" ... Доктор, у вас что-то не то с кодировкой!
arsvasimov Java Developer в Phractal Client
29 мая 2025, 09:48
😂
Denys Sukhoivan
Уровень 30
Expert
10 августа 2023, 13:26
Ничего не понятно, но очень интересно )))
26 сентября 2022, 06:30
просто прочитал вообще не вникая. Не сумели заинтересовать т.к. не написано где это будет применяться и на сколько оно важно. Если оно пригодится раз в 10 лет то можно и нагуглить потом как определить кодировку или с одной в другую перегнать.
DmitryStudent в Home
25 января 2023, 12:21
Как будто ты ни разу не сталкивался с тем, что вместо текста видишь какие-то закорючки, особенно если используешь кириллицу в американском ПО.
Lafaed
Уровень 36
3 марта 2023, 16:49
Не то чтоб не заинтересовали, скорее просто не зашло как-то.
Тимофей
Уровень 51
17 июня 2023, 17:41
чувак я на работе с этой задачей жестко завис, на несколько дней. Документы могут быть загружены в windows-1251, а после обработки парсером они станут кракозябрами, а пользователям оно не к чему. Ты не представляешь какое это болото, я написал все методы, написал тесты, а потом оказалось когда я мавеном прогнал тесты - что мавен windows 1251 использует, а не UTF-8 и теперь нужно уже это решать. Какая же боль эти кодировки
ДмитрийСтудент в мгу(вмк)/мфюа
22 июля 2022, 15:45
Огонь hкодировки