— Привіт, Аміго!
Зараз буде ще одна цікава тема – кодування.
Можливо, ти десь уже чув, що кожен символ має код (число). Саме тому тип char вважається не лише символьним, а й числовим типом.
Наприклад, код символу А англійського алфавіту – 65. B – 66, C – 67 і так далі. Свої коди є у великих літер і у маленьких, у російських літер, у китайських (ага, багато, багато кодів), цифр, різних символів – словом практично у всього, що можна назвати символом.
— Тобто. кожній літері чи кожному символу відповідає якесь число?
— Так, саме так.
Символ можна перетворити на число, а число на символ. Java взагалі практично не бачить різниці між ними:
char c = 'A'; //код(число) літери А – 65
c++; //Тепер містить число 66 – код літери B
— Цікаво.
— Так ось, кодуванням називається набір символів і відповідний набір кодів. Тільки таких кодувань вигадали не одне, а досить багато. А потім з'явилася універсальна – Unicode.
Хоча скільки б універсальних стандартів не придумали, від старих ніхто відмовлятися не поспішає. І все виходить прямо як на цій картинці:
Ось уяви, що Вася та Коля захотіли самостійно придумати кодування.
От кодування Васі:
А ось кодування Колі:
Вони навіть використовують ті самі символи, але коди у цих символів різні.
І ось коли рядок «ABC-123» у кодуванні Васі записують у файл, туди пишеться набір байт:
А тепер цей файл хоче прочитати іншу програму, яка використовує кодування Колі:
Ось що вона прочитає«345-IJK»
І найгірше те, що зазвичай ніде у файлі тип кодування не зберігається, і розробникам програм доводиться вгадувати їх.
— А як їх вгадувати?
— Це окрема тема. Але я хочу тобі розповісти, як працювати з кодуванням. Як ти вже знаєш, розмір типу char у Java – два байти. І рядки Java мають формат Unicode.
Але Java дозволяє перетворити рядок на набір байт будь-якого відомого кодування. Для цього є спеціальні методи класу String(!). Також Java має спеціальний клас Charset, який описує конкретне кодування.
1) Як отримати список усіх кодувань, з якими Java може працювати?
Для цього є спеціальний статичний метод доступнийCharsets. Цей метод повертає набір пар (ім'я кодування, об'єкт, що описує кодування)
SortedMap<String,Charset> charsets = Charset.availableCharsets();
У кожного кодування є унікальне ім'я, ось деякі з них: UTF-8, UTF-16, Windows-1251, KOI8-R,…
2) Як отримати поточне активне кодування (Unicode)?
Для цього є спеціальний метод defaultCharset
Charset currentCharset = Charset.defaultCharset();
3) Як перетворити рядок на певне кодування?
У Java на основі рядка можна створити масив байт у будь-якому відомому Java кодуванні:
Метод | Приклад |
---|---|
|
|
|
|
|
|
4) А як перетворити набір байт, які я прочитав з файлу в рядок, якщо я знаю, в якому кодуванні вони були у файлі?
Тут все ще простіше – клас String має спеціальний конструктор:
Метод | Приклад |
---|---|
|
|
|
|
|
|
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);
— Я так і думав. Дякую за цікаву лекцію, Ріша.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ