Где взять строковый литерал «UTF-8» в Java?

490

Я пытаюсь использовать константу вместо строкового литерала в этом фрагменте кода:

new InputStreamReader(new FileInputStream(file), "UTF-8")

"UTF-8"появляется в коде довольно часто, и было бы намного лучше обратиться к некоторой static finalпеременной вместо этого. Вы знаете, где я могу найти такую ​​переменную в JDK?

Кстати, подумав, такие константы - плохой дизайн: публичные статические литералы ... не являются решением для дублирования данных

yegor256
источник
11
Смотрите этот вопрос .
высоким содержанием кофеина
1
Примечание: если вы уже на Java 7, используйте Files.newBufferedWriter(Path path, Charset cs)из NIO.
Франклин Ю

Ответы:

836

В Java 1.7+ java.nio.charset.StandardCharsets определяет константы для Charsetвключения UTF_8.

import java.nio.charset.StandardCharsets;

...

StandardCharsets.UTF_8.name();

Для Android: minSdk 19

Роджер
источник
3
Вы используете .toString () на этом?
Мэтт Брукхёйс
54
.toString()будет работать, но правильная функция есть .name(). 99,9% toString не является ответом.
Роджер
1
Кстати .displayName(), также будет работать, если он не переопределен для локализации, как предполагалось.
Роджер
36
Вам не нужно name()вообще звонить . Вы можете напрямую передать Charsetобъект в InputStreamReaderконструктор.
Natix,
6
И есть другие либы, которые требуют String, возможно, по наследственным причинам. В таких случаях я сохраняю Charsetобъект, обычно получаемый из него StandardCharsets, и использую name()при необходимости.
Magnilex
134

Сейчас я использую org.apache.commons.lang3.CharEncoding.UTF_8константу от commons-lang .

yegor256
источник
4
Для тех , кто использует Lang 3.0: org.apache.commons.lang3.CharEncoding.UTF_8. (Примечание «lang3»).
Рассел Сильва
24
Если вы используете Java 1.7, см. Ответ @ Roger's ниже, поскольку он является частью стандартной библиотеки.
Дрю Стивенс
2
PS "@ Роджер ответ ниже" теперь @ Роджер ответ выше . ☝
Гэри С.
Этот класс устарел, так как Java 7 представляет java.nio.charset.StandardCharsets
sendon1982
66

В библиотеке Google Guava (которую я очень рекомендую, если вы работаете в Java) есть Charsetsкласс со статическими полями, такими как Charsets.UTF_8, Charsets.UTF_16и т. Д.

Начиная с Java 7 вы должны просто использовать java.nio.charset.StandardCharsetsвместо этого для сопоставимых констант.

Обратите внимание, что эти константы не являются строками, они актуальны Charset экземпляры. Все стандартные API, которые принимают имя набора символов, также имеют перегрузку, которая принимает Charsetобъект, который вы должны использовать вместо этого.

Даниэль Приден
источник
3
Итак, должно ли быть Charsets.UTF_8.name ()?
Алик Эльзин-килака
1
@kilaka Да, используйте name () вместо getDisplayName (), поскольку name () является окончательным, а getDisplayName ()
RKumsher
3
@Buffalo: Пожалуйста, прочитайте мой ответ еще раз: он рекомендует по java.nio.charset.StandardCharsetsвозможности использовать, который не является сторонним кодом. Кроме того, определения кодировок Guava не постоянно изменяются, и AFAIK никогда не нарушал обратную совместимость, поэтому я не думаю, что ваша критика оправдана.
Даниэль Приден
2
@Buffalo: Это так и может быть, но я сомневаюсь, что ваши проблемы имели какое-либо отношение к Charsetsклассу. Если вы хотите пожаловаться на гуаву, это нормально, но это не место для этих жалоб.
Даниэль Приден
1
Пожалуйста, не включайте мультимегабайтную библиотеку, чтобы получить одну строковую константу.
Джеффри Блаттман
50

В случае, если эта страница появляется в чьём-либо поиске в Интернете, начиная с Java 1.7, теперь вы можете использовать java.nio.charset.StandardCharsets, чтобы получить доступ к постоянным определениям стандартных кодировок.

cosjav
источник
Я пытался использовать это, но это не похоже на работу. 'Charset.defaultCharset ());' Кажется, работает после включения 'java.nio.charset. *', но я не могу явно ссылаться на UTF8, когда я пытаюсь использовать 'File.readAllLines'.
Роджер
1
@ Роджер В чем проблема? Из того, что я вижу, вы можете просто позвонить:Files.readAllLines(Paths.get("path-to-some-file"), StandardCharsets.UTF_8);
Cosjav
Я не знаю, в чем заключалась проблема, но она сработала для меня после того, как я что-то помнил.
Роджер
1
^^^ Возможно, вам пришлось изменить целевую платформу в IDE. Если 1.6 был вашим последним JDK, когда вы устанавливали IDE, он, вероятно, выбрал его в качестве значения по умолчанию и оставил его в качестве значения по умолчанию еще долго после того, как вы обновили IDE и JDK сами по себе.
Bitbang3r
10

Эта константа доступна ( в том числе , как: UTF-16, US-ASCIIи т.д.) в классе , org.apache.commons.codec.CharEncodingа также.

Альфредо Каррильо
источник
9

Их нет (по крайней мере, в стандартной библиотеке Java). Наборы символов варьируются от платформы к платформе, поэтому в Java их нет стандартного списка.

Однако есть некоторые сторонние библиотеки, которые содержат эти константы. Одним из них является Guava (основные библиотеки Google): http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Charsets.html

tskuzzy
источник
Мне потребовалась секунда, чтобы понять это ... Константы Charsets в Guava - это (не удивительно) Charsets, а не Strings. InputStreamReader имеет другой конструктор, который принимает Charset, а не строку. Если вам действительно нужна строка, это, например, Charsets.UTF_8.name ().
Эд Штауб
1
Наборы символов могут варьироваться от платформы к платформе, но UTF-8 гарантированно существует.
tar
3
Все кодировки, определенные в StandardCharsets, гарантированно существуют в каждой реализации Java на каждой платформе.
Кшиштоф Красонь
8

Вы можете использовать Charset.defaultCharset()API илиfile.encoding свойство.

Но если вам нужна собственная константа, вам нужно определить ее самостоятельно.

paulsm4
источник
11
Набор символов по умолчанию обычно определяется настройками ОС и локали, я не думаю, что есть какая-либо гарантия, что он останется неизменным для нескольких вызовов Java. Так что это не замена для постоянного разделения "UTF-8".
Йорн Хорстманн
6

В Java 1.7+

Не используйте строку «UTF-8», вместо этого используйте Charsetпараметр типа:

import java.nio.charset.StandardCharsets

...

new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8);
Мостафа Ватанпур
источник
4

Если вы используете OkHttp для Java / Android, вы можете использовать следующую константу:

import com.squareup.okhttp.internal.Util;

Util.UTF_8; // Charset
Util.UTF_8.name(); // String
JJD
источник
2
он удален из OkHttp, поэтому следующий путь: Charset.forName("UTF-8").name()когда вам нужна поддержка более низкого Android, чем API 19+, в противном случае вы можете использовать:StandardCharsets.UTF_8.name()
mtrakal
3

Постоянные определения для стандарта. Эти кодировки гарантированно будут доступны во всех реализациях платформы Java. с 1,7

 package java.nio.charset;
 Charset utf8 = StandardCharsets.UTF_8;
Вазген Торосян
источник
0

Класс org.apache.commons.lang3.CharEncoding.UTF_8устарел после появления Java 7java.nio.charset.StandardCharsets

  • @ см. имена кодировки символов JRE
  • @ Since 2.1
  • @deprecated Java 7 представила {@link java.nio.charset.StandardCharsets}, которая определяет эти константы как
  • {@link Charset} объекты. Используйте {@link Charset # name ()}, чтобы получить строковые значения, предоставленные в этом классе.
  • Этот класс будет удален в будущем выпуске.
sendon1982
источник