„Здрасти, Амиго!“

„Сега е време за друга интересна тема: codeировките.“

„Може би вече сте чували някъде, че всеки символ има code (число). Ето защо типът char може да представлява Howто символи, така и числа.“

„Например codeът на буквата „А“ в английската азбука е 65. „В“ е 66, „С“ е 67 и т.н. Има уникални codeове за главни букви, малки букви, кирorца, китайски знаци (да, много и много codeове), числа и различни символи. Накратко, има code за почти всичко, което бихте нарекли знак."

„Значи всяка буква и знак съответстват на няHowво число?“

"Точно."

"Един знак може да бъде преобразуван в число и число в знак. Java обикновено не вижда разлика между тях:"

char c = 'A'; //The code (number) for 'A' is 65
c++; //Now c contains the number 66, which is the code for 'B'

— Интересно.

„И така, едно codeиране е набор от символи и съответния им набор от codeове. Но не е изобретено само едно codeиране – има доста. Едва по-късно беше изобретено общо универсално codeиране, Unicode.“

"Но колкото и универсални стандарти да са измислени, никой не бърза да изостави старите. И тогава всичко се случва точно като в този анимационен филм:"

Кодиране на знаци - 1

„Представете си, че Винсент и Ник решат да направят свои собствени codeировки.“

„Ето codeирането на Винсент:“
Кодиране на знаци - 2

„И ето codeирането на Ник:“
Кодиране на знаци - 3

„Те дори използват едни и същи знаци, но codeовете за знаците са различни.“

„Когато низът „ABC-123“ се запише във файл с помощта на codeирането на Vincent, получаваме следния набор от byteове:“
Кодиране на знаци - 4

„И сега друга програма, която използва codeирането на Ник, иска да прочете file:“

„Ето Howво ще гласи: «345-IJK».“

„И най-лошото е, че codeировките обикновено не се съхраняват никъде във файлове, така че разработчиците трябва да гадаят.“

— Е, How ги отгатват?

„Това е друга тема. Но искам да обясня How се работи с codeировки. Както вече знаете, размерът на знак в Java е два byteа. И низовете на Java използват формата Unicode.“

„Но Java ви позволява да конвертирате String в набор от byteове във всяко codeиране, което познава. Класът String има специални методи за това. Java също има специален клас Charset, който описва специфично codeиране.“

1) Как да получа списък с всички codeировки, които Java поддържа?

"За това има специален статичен метод, наречен availableCharsets. "Този метод връща набор от двойки (име на codeиране, обект, който описва codeирането):"

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

„Всяко codeиране има уникално име. Ето някои от тях: UTF-8, UTF-16, Windows-1251, KOI8-R,…“

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

„ За това има специален метод, наречен defaultCharset .

Charset currentCharset = Charset.defaultCharset();

3) Как да конвертирам низ в конкретно codeиране?

„В Java можете да конвертирате низ в byteов масив във всяко codeиране, което 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) Как да преобразувам масив от byteове, който чета от файл, в низ, ако знам Howво е codeирането му във file?

"Това е още по-лесно. Класът 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) Как да конвертирам byteов масив от едно codeиране в друго?

„Има много начини. Ето един от най-простите:“

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);

„Така си помислих. Благодаря за интересния урок, Риши.“