| Главная » Статьи » Java » Java Ranger Basic |
День 16/21
| Encodings Рассмотрим пример: public static void main(String args) throws UnsupportedEncodingException { System.out.println("A".getBytes("UTF-16").length); System.out.println("AA".getBytes("UTF-16").length); } //output > 4 > 6 В первом случае мы получили 4 байта. Неприятно, что одна буква закодирована в 4 байтах. Но странно, что в строке, в которой в два раза больше букв, 6 байт. Дело в том, что в первых двух байтах хранится информация о кодировке. Для строки из 5 букв размер будет 12 байт: System.out.println("AAAAA".getBytes("UTF-16").length); //output > 12 В Java кодировка по умолчанию – «UTF-8». Но вообще UTF (Unicode Transformation Format) кодировок несколько форм: UTF-8, UTF-16 (UTF-16BE, UTF-16LE) и UTF-32 (UTF-32BE, UTF-32LE). UTF – это семейство кодировок. Кодировка может быть с постоянной и переменной длиной. Кодировки UTF-8 (длина от 1 до 4 байта на символ) и UTF-16 (2 или 4 байта на символ) – переменной длины, а UTF-32 (всегда 4 байта на символ) – постоянной. UTF-8 редкие буквы кодирует большими массивами, но часто и короткими. Из-за этого он вроде как он в 4 раза более упакованный, но некоторые символы у него больше 1 байта. Но если у нас есть большой файл и нам нужна миллионная буква, мы не можем отмерять ее сначала, потому что разные буквы занимают разное пространство, придется идти сначала и отсчитывать буквы, в отличие от UTF-32. Символы Кодировка Размер A UTF-8 1 байт A UTF-16 4 байта ЭЮЯ UTF-8 6 байт ЭЮЯ cp1251 3 байта Получается, что кириллические символы в кодировке UTF-8 кодируются хуже. Почему char удобен и подогнан под такой стандарт, как Unicode? Одна из причин – глобализация (ОС под разные страны) и вторая – интернет. Но собрать даже Character Set – это огромная проблема. На сегодня самый популярный Coded Character Set – это Unicode, и он фактически один, все его признали и перешли на него. Он пронумеровал порядка 110 тысяч символов, они добавили очень много языков, включая мертвые языки. Это означает, что если мы оперируем Unicode, то можно все писать в одном стиле. В Unicode 110 тысяч символов, но их числа идут не подряд. Например, от 0 до 10000 стоят такие-то символы, от 10000 до 11000 ничего нет. Номера не обязаны присваиваться подряд. Unicode развивается, на данный момент актуальна его версия 7.0. Когда появилась Java (1995-1996 год), версия Unicode была порядка ~3, и там было пронумеровано меньше 65 тысячи символов. Поэтому тогда в Джаве выбрали подходящий по размеру тип – char. И тогда номер буквы в Unicode соответствовал номеру char в Java, потому что количество символов умещалось в диапазон char. Но Unicode продолжала развиваться, с каждой новой версией добавлялись новые символы. И за последние 10 лет уже получилось более 110 тысяч символов, еще и при том, что они занимают диапазон где-то до 200 тысяч (из-за пропусков). В char эти символы стали не помещаться. И пришлось придумать специальное правило, что делать, когда символ Unicode такой большой, что в один char не помещается – приходится хранить его двумя char. Unicode – это fixed-length encoding, то есть она по правилам может кодировать чуть больше 1 миллиона codepoints (больше не может), но на сегодня пронумеровали порядка 110 тысяч, они лежат не сплошняком, а где-то от 0 до 200 тысяч. Есть также кодировки переменной длины – variable-length encoding и тут кодировки разные. Они берут, например, 256 самых популярных букв и кодируют их одним байтом, а менее популярные буквы кодируются двумя байтами, а еще менее популярные – тремя байтами. И тут оказывается, что в разных местах Земли разные самые популярные 256 букв. Обычно они в один байт: от 0 до 127 кодируют английские буквы, а в оставшиеся значения от 128 до 255 разные страны хотят поставить свои самые популярные буквы. У Windows для каждой страны разработана своя кодировка, для славянских языков – cp1251. Конкретно правило преобразование Юникода в массив байтов в Джаве по умолчанию – это UTF-8. У строк выбора нет – они всегда раскладывают массив int codepoint’ов в масив char по UTF-16 и мы этим управлять не можем. Таким образом у нас массив байт преобразуется и внутри строки у нас массив char. Перенос строки обозначаeтся, как: \n (в Linux), \r\n (в Windows), \r (в MacOS). По умолчанию в любой JVM обязано быть 6 кодировок: ISO-8859-1, US-ASCII, UTF-16, UTF-16BE, UTF-16LE, UTF-8. Их можно все найти в виде констант в классе java.nio.charset.StandardCharsets. Но в каждой конкретной JVM кодировок могут поставить больше (обычно около 170). В следующей теме мы рассмотрим: Operators Источник: http://becomejavasenior.com/courses/?utm_source=Java+Email+Courses&utm_campaign=aa710df388-JavaRangerBasicIntro&utm_medi | |
| Просмотров: 535 | | |
| Всего комментариев: 0 | |