Проблемы с кодировками сами по себе сбивают с толку и усложняют, но, кроме того, вы должны помнить точные имена ваших кодировок. Это "utf8"
? Или "utf-8"
? Или может быть "UTF-8"
? При поиске примеров кода в интернете вы увидите все вышеперечисленное. Почему бы просто не сделать их именованными константами и использовать Charset.UTF8
?
211
MessageDigest#getInstance()
Кстати, та же история продолжается .Ответы:
Простой ответ на заданный вопрос заключается в том, что доступные строки charset варьируются от платформы к платформе.
Тем не менее, есть шесть, которые должны присутствовать, поэтому константы могли быть сделаны для тех, кто давно. Я не знаю, почему они не были.
JDK 1.4 сделал отличную вещь, представив тип Charset. На этом этапе они больше не хотели бы предоставлять строковые константы, поскольку цель состоит в том, чтобы заставить всех использовать экземпляры Charset. Так почему же тогда не предоставить шесть стандартных констант Charset? Я спросил Мартина Буххольца, так как он сидит рядом со мной, и он сказал, что не было действительно особой причины, за исключением того, что в то время все еще не получилось - слишком мало API JDK было модифицировано для принять Charset, и из тех, которые были, перегрузки Charset обычно выполнялись немного хуже.
Печально, что только в JDK 1.6 они наконец-то закончили оснащение перегрузками Charset. И что эта ситуация с производительностью в обратном направлении все еще существует (причина, почему это невероятно странно, и я не могу это объяснить, но это связано с безопасностью!).
Короче говоря - просто определите свои собственные константы или используйте класс Charsets Guava, с которым связан Тони Пони (хотя эта библиотека на самом деле еще не выпущена).
Обновление:
StandardCharsets
класс в JDK 7.источник
String(byte bytes[], int offset, int length, Charset charset)
это реализовано. На самом деле, при создании маленькой строки из большого байта совсем не просто падение производительности.Два года спустя и StandardCharsets в Java 7 теперь определяют константы для 6 стандартных наборов символов.
Если вы застряли на Java 5/6, вы можете использовать гуавы в Charsets константы, как это было предложено Кевин Bourrillion и Джон тарелочкам.
источник
Я бы сказал, что мы можем добиться гораздо большего ... почему не гарантированно доступны доступные кодировки?
Charset.UTF8
должна быть ссылкой наCharset
, а не на имя в виде строки. Таким образом, нам не придется справлятьсяUnsupportedEncodingException
повсюду.Имейте в виду, я также думаю, что .NET выбрал лучшую стратегию, по умолчанию везде UTF-8. Затем он облажался, просто назвав свойство кодировки «по умолчанию для операционной системы»
Encoding.Default
- что не является значением по умолчанию в самом .NET :(Возвращаясь к разглагольствованиям о поддержке кодировки Java - почему нет конструктора для
FileWriter
/,FileReader
который принимаетCharset
? По сути, это практически бесполезные классы из-за этого ограничения - вам почти всегда нуженInputStreamReader
округленныйFileInputStream
или эквивалентный для вывода :(Медсестра, медсестра - где мое лекарство?
РЕДАКТИРОВАТЬ: Мне приходит в голову, что это на самом деле не ответил на вопрос. Реальный ответ, по-видимому, либо «никто не думал об этом», либо «кто-то думал, что это плохая идея». Я настоятельно рекомендую, чтобы внутренние служебные классы, предоставляющие имена или кодировки, избегали дублирования вокруг кодовой базы ... Или вы могли бы просто использовать тот, который мы использовали в Google, когда этот ответ был впервые написан . (Обратите внимание, что с Java 7 вы бы просто использовали
StandardCharsets
вместо этого.)источник
В Java 1.7
import java.nio.charset.StandardCharsets
например:
StandardCharsets.UTF_8
StandardCharsets.US_ASCII
источник
Текущее состояние API кодирования оставляет желать лучшего. Некоторые части Java 6 API не принимают
Charset
вместо строки (вlogging
,dom.ls
,PrintStream
, могут быть и другие). Это не помогает, если предполагается, что кодировки имеют разные канонические имена для разных частей стандартной библиотеки.Я могу понять, как вещи попали туда, где они есть; не уверен, что у меня есть блестящие идеи о том, как их исправить.
Как в сторону...
Вы можете посмотреть имена для реализации Java 6 Sun здесь .
Для UTF-8 канонические значения предназначены
"UTF-8"
дляjava.nio
и"UTF8"
дляjava.lang
иjava.io
. Единственные кодировки, которые спецификация требует для поддержки JRE: US-ASCII; ISO-8859-1; UTF-8; UTF-16BE; UTF-16LE; UTF-16 .источник
Я давно определил служебный класс с константами Charset UTF_8, ISO_8859_1 и US_ASCII.
Кроме того , некоторые давно ( от 2 лет) , я сделал простой тест производительности между
new String( byte[], Charset )
иnew String( byte[], String charset_name )
и обнаружил , что последняя реализация ЗНАЧИТЕЛЬНО быстрее. Если вы посмотрите изнутри на исходный код, вы увидите, что он действительно следует совершенно другим путем.По этой причине я включил утилиту в том же классе
Почему конструктор String (byte [], Charset) не делает то же самое, лучше меня.
источник
Charset
нужно регистрироваться, поэтому исключение может произойти. IIRC, в JDK7 были внесены некоторые изменения, чтобы сделать его быстрее для хорошо известныхCharset
реализаций (исключите лишнюю копию).