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


490

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

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

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

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



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 .


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, чтобы получить доступ к постоянным определениям стандартных кодировок.


Я пытался использовать это, но это не похоже на работу. '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


9

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

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


Мне потребовалась секунда, чтобы понять это ... Константы Charsets в Guava - это (не удивительно) Charsets, а не Strings. InputStreamReader имеет другой конструктор, который принимает Charset, а не строку. Если вам действительно нужна строка, это, например, Charsets.UTF_8.name ().
Эд Штауб

1
Наборы символов могут варьироваться от платформы к платформе, но UTF-8 гарантированно существует.
tar

3
Все кодировки, определенные в StandardCharsets, гарантированно существуют в каждой реализации Java на каждой платформе.
Кшиштоф Красонь

8

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

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


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

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 ()}, чтобы получить строковые значения, предоставленные в этом классе.
  • Этот класс будет удален в будущем выпуске.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.