¿Dónde obtener el literal de cadena "UTF-8" en Java?

490

Estoy tratando de usar una constante en lugar de un literal de cadena en este fragmento de código:

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

"UTF-8" aparece en el código con bastante frecuencia, y sería mucho mejor hacer referencia a algunos static final variable en su lugar. ¿Sabes dónde puedo encontrar esa variable en JDK?

Por cierto, pensándolo bien, tales constantes son un mal diseño: los literales estáticos públicos ... no son una solución para la duplicación de datos

yegor256
fuente
11
Ver esta pregunta .
altamente cafeinado
1
Nota: si ya está en Java 7, utilícelo Files.newBufferedWriter(Path path, Charset cs)desde NIO.
Franklin Yu

Respuestas:

836

En Java 1.7+, java.nio.charset.StandardCharsets define constantes para Charsetincluir UTF_8.

import java.nio.charset.StandardCharsets;

...

StandardCharsets.UTF_8.name();

Para Android: minSdk 19

Roger
fuente
3
¿Usas .toString () en eso?
Matt Broekhuis
54
.toString()funcionará pero la función adecuada es .name(). 99.9% toString no es la respuesta.
Roger
1
BTW .displayName()también funcionará a menos que se anule para la localización según lo previsto.
Roger
36
Realmente no necesitas llamar name()en absoluto. Puede pasar directamente el Charsetobjeto al InputStreamReaderconstructor.
Natix
66
Y hay otras bibliotecas por ahí que requieren una String, tal vez por razones heredadas. En tales casos, mantengo un Charsetobjeto alrededor, típicamente derivado de StandardCharsets, y lo uso name()si es necesario.
Magnilex
134

Ahora uso org.apache.commons.lang3.CharEncoding.UTF_8constante de commons-lang .

yegor256
fuente
44
Para aquellos que utilizan Lang 3.0: org.apache.commons.lang3.CharEncoding.UTF_8. (Nota "lang3").
Russell Silva
24
Si está utilizando Java 1.7, consulte la respuesta de @ Roger a continuación, ya que es parte de la biblioteca estándar.
Drew Stephens
2
PD "La respuesta de @ Roger a continuación" es ahora la respuesta de @ Roger arriba . ☝
Gary S.
Esa clase está en desuso porque Java 7 introduce java.nio.charset.StandardCharsets
sendon1982
66

El Google guayaba biblioteca (que recomiendo altamente todos modos, si usted está haciendo el trabajo en Java) tiene una Charsetsclase con campos estáticos como Charsets.UTF_8, Charsets.UTF_16, etc.

Desde Java 7 deberías usar solo java.nio.charset.StandardCharsetspara constantes comparables.

Tenga en cuenta que estas constantes no son cadenas, son Charsetinstancias reales . Todas las API estándar que toman un nombre de juego de caracteres también tienen una sobrecarga que toma un Charsetobjeto que debe usar en su lugar.

Daniel Pryden
fuente
3
Entonces, ¿debería ser Charsets.UTF_8.name ()?
AlikElzin-kilaka
1
@kilaka Sí, use name () en lugar de getDisplayName () ya que name () es final y getDisplayName () no lo es
RKumsher
3
@Buffalo: Por favor lea mi respuesta nuevamente: recomienda usar java.nio.charset.StandardCharsetscuando sea posible, que no es código de terceros. Además, las definiciones de Guava Charsets no se "modifican constantemente" y AFAIK nunca ha roto la compatibilidad con versiones anteriores, por lo que no creo que su crítica esté justificada.
Daniel Pryden
2
@Buffalo: Así es como puede ser, pero dudo que tus problemas tengan algo que ver con la Charsetsclase. Si quiere quejarse de la guayaba, está bien, pero este no es el lugar para esas quejas.
Daniel Pryden
1
No incluya una biblioteca de varios megabytes para obtener una cadena constante.
Jeffrey Blattman
50

En caso de que esta página aparezca en la búsqueda web de alguien, a partir de Java 1.7 ahora puede usar java.nio.charset.StandardCharsets para obtener acceso a definiciones constantes de charsets estándar.

cosjav
fuente
He estado tratando de usar esto, pero no parece funcionar. 'Charset.defaultCharset ());' parece funcionar después de incluir 'java.nio.charset. *' pero parece que no puedo referirme explícitamente a UTF8 cuando intento usar 'File.readAllLines'.
Roger
1
@Roger ¿Cuál parece ser el problema? Por lo que puedo ver que sólo puede llamar a:Files.readAllLines(Paths.get("path-to-some-file"), StandardCharsets.UTF_8);
cosjav
No sé cuál fue el problema, pero funcionó para mí después de cambiar algo que no puedo recordar.
Roger
1
^^^ Probablemente tuvo que cambiar la plataforma de destino en el IDE. Si 1.6 fue su último JDK cuando instaló el IDE, probablemente lo eligió como predeterminado y lo mantuvo como predeterminado mucho después de que haya actualizado tanto el IDE como el JDK en su lugar.
Bitbang3r
10

Esta constante está disponible (entre otros como: UTF-16, US-ASCII, etc.) en la clase org.apache.commons.codec.CharEncodingasí.

Alfredo Carrillo
fuente
9

No hay ninguno (al menos en la biblioteca estándar de Java). Los conjuntos de caracteres varían de una plataforma a otra, por lo que no hay una lista estándar de ellos en Java.

Sin embargo, hay algunas bibliotecas de terceros que contienen estas constantes. Una de ellas es Guava (bibliotecas principales de Google): http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Charsets.html

tskuzzy
fuente
Me tomó un segundo entender esto ... Las constantes de los Charsets de la guayaba son (no es de extrañar) Charsets, no Strings. InputStreamReader tiene otro constructor que toma un conjunto de caracteres en lugar de una cadena. Si realmente necesita la cadena, es, por ejemplo, Charsets.UTF_8.name ().
Ed Staub
1
Los juegos de caracteres pueden variar de una plataforma a otra, pero se garantiza que UTF-8 existe.
alquitrán el
3
StandardCharsetsSe garantiza que todos los charsets definidos en existen en cada implementación de Java en cada plataforma.
Krzysztof Krasoń
8

Puede usar Charset.defaultCharset()API o file.encodingpropiedad.

Pero si quieres tu propia constante, deberás definirla tú mismo.

paulsm4
fuente
11
El conjunto de caracteres predeterminado generalmente está determinado por el sistema operativo y la configuración regional, no creo que haya ninguna garantía de que siga siendo el mismo para múltiples invocaciones de Java. Por lo tanto, esto no reemplaza a un constante "septificante" utf-8 ".
Jörn Horstmann
6

En Java 1.7+

No use la cadena "UTF-8", en su lugar use el Charsetparámetro tipo:

import java.nio.charset.StandardCharsets

...

new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8);
Mostafa Vatanpour
fuente
4

Si está utilizando OkHttp para Java / Android, puede usar la siguiente constante:

import com.squareup.okhttp.internal.Util;

Util.UTF_8; // Charset
Util.UTF_8.name(); // String
JJD
fuente
2
se elimina de OkHttp, por lo que la siguiente forma es: Charset.forName("UTF-8").name()cuando necesite soporte para Android inferior a API 19+, de lo contrario puede usar:StandardCharsets.UTF_8.name()
mtrakal
3

Definiciones constantes para el estándar. Se garantiza que estos conjuntos de caracteres estarán disponibles en todas las implementaciones de la plataforma Java. desde 1.7

 package java.nio.charset;
 Charset utf8 = StandardCharsets.UTF_8;
Vazgen Torosyan
fuente
0

La clase org.apache.commons.lang3.CharEncoding.UTF_8está en desuso después de la introducción de Java 7java.nio.charset.StandardCharsets

  • @ver nombres de codificación de caracteres JRE
  • @ desde 2.1
  • @deprecated Java 7 introdujo {@link java.nio.charset.StandardCharsets}, que define estas constantes como
  • {@link Charset} objetos. Use {@link Charset # name ()} para obtener los valores de cadena proporcionados en esta clase.
  • Esta clase se eliminará en una versión futura.
sendon1982
fuente