Woher bekommt man das String-Literal "UTF-8" in Java?

490

Ich versuche in diesem Code eine Konstante anstelle eines String-Literal zu verwenden:

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

"UTF-8"erscheint ziemlich oft im Code und es wäre viel besser, static finalstattdessen auf eine Variable zu verweisen . Wissen Sie, wo ich eine solche Variable in JDK finden kann?

Übrigens, bei einem zweiten Gedanken sind solche Konstanten ein schlechtes Design: Öffentliche statische Literale ... sind keine Lösung für die Duplizierung von Daten

yegor256
quelle
11
Siehe diese Frage .
koffeinhaltig
1
Hinweis: Wenn Sie bereits mit Java 7 arbeiten, verwenden Sie Files.newBufferedWriter(Path path, Charset cs)NIO.
Franklin Yu

Antworten:

836

In Java 1.7+ definiert java.nio.charset.StandardCharsets Konstanten für das CharsetEinschließen UTF_8.

import java.nio.charset.StandardCharsets;

...

StandardCharsets.UTF_8.name();

Für Android: minSdk 19

Roger
quelle
3
Verwenden Sie dazu .toString ()?
Matt Broekhuis
54
.toString()wird funktionieren, aber die richtige Funktion ist .name(). 99,9% toString ist nicht die Antwort.
Roger
1
Übrigens .displayName()funktioniert es auch, wenn es nicht wie vorgesehen für die Lokalisierung überschrieben wird.
Roger
36
Sie müssen überhaupt nicht anrufen name(). Sie können das CharsetObjekt direkt an den InputStreamReaderKonstruktor übergeben.
Natix
6
Und es gibt andere Bibliotheken da draußen, die eine benötigen String, vielleicht aus alten Gründen. In solchen Fällen behalte ich ein CharsetObjekt in der Nähe, das normalerweise von abgeleitet ist StandardCharsets, und verwende es name()bei Bedarf.
Magnilex
134

Jetzt benutze ich org.apache.commons.lang3.CharEncoding.UTF_8Konstante von commons-lang .

yegor256
quelle
4
Für diejenigen, die Lang 3.0 verwenden : org.apache.commons.lang3.CharEncoding.UTF_8. (Hinweis "lang3").
Russell Silva
24
Wenn Sie Java 1.7 verwenden, lesen Sie die Antwort von @ Roger weiter unten, da es Teil der Standardbibliothek ist.
Drew Stephens
2
PS "@ Rogers Antwort unten" ist jetzt @ Rogers Antwort oben . ☝
Gary S.
Diese Klasse ist veraltet, da Java 7 java.nio.charset.StandardCharsets einführt
sendon1982
66

Die Google Guava - Bibliothek (die ich sehr sowieso empfehlen würde, wenn Sie tun , sind Arbeit in Java) , die eine hat CharsetsKlasse mit statischen Feldern wie Charsets.UTF_8, Charsets.UTF_16usw.

Seit Java 7 sollten Sie java.nio.charset.StandardCharsetsstattdessen nur für vergleichbare Konstanten verwenden.

Beachten Sie, dass diese Konstanten keine Zeichenfolgen sind, sondern tatsächliche CharsetInstanzen. Alle Standard-APIs, die einen Zeichensatznamen verwenden, haben auch eine Überladung, die ein CharsetObjekt akzeptiert, das Sie stattdessen verwenden sollten.

Daniel Pryden
quelle
3
Sollte also Charsets.UTF_8.name () sein?
AlikElzin-Kilaka
1
@kilaka Ja, benutze name () anstelle von getDisplayName (), da name () endgültig ist und getDisplayName () nicht
RKumsher
3
@ Buffalo: Bitte lesen Sie meine Antwort noch einmal: Es wird empfohlen, java.nio.charset.StandardCharsetswenn möglich zu verwenden, was kein Code von Drittanbietern ist. Darüber hinaus werden die Definitionen der Guava-Zeichensätze nicht "ständig geändert", und AFAIK hat die Abwärtskompatibilität nie unterbrochen, sodass ich Ihre Kritik nicht für gerechtfertigt halte.
Daniel Pryden
2
@ Buffalo: So mag es sein, aber ich bezweifle, dass deine Probleme irgendetwas mit der CharsetsKlasse zu tun hatten . Wenn Sie sich über Guave beschweren möchten, ist das in Ordnung, aber dies ist nicht der richtige Ort für diese Beschwerden.
Daniel Pryden
1
Bitte fügen Sie keine Multi-Megabyte-Bibliothek hinzu, um eine Zeichenfolgenkonstante zu erhalten.
Jeffrey Blattman
50

Falls diese Seite in einer Websuche angezeigt wird, können Sie ab Java 1.7 jetzt java.nio.charset.StandardCharsets verwenden , um Zugriff auf konstante Definitionen von Standardzeichensätzen zu erhalten.

cosjav
quelle
Ich habe versucht, dies zu verwenden, aber es scheint nicht zu funktionieren. 'Charset.defaultCharset ());' scheint zu funktionieren, nachdem 'java.nio.charset. *' eingefügt wurde, aber ich kann nicht explizit auf UTF8 verweisen, wenn ich versuche, 'File.readAllLines' zu verwenden.
Roger
1
@ Roger Was scheint das Problem zu sein? Files.readAllLines(Paths.get("path-to-some-file"), StandardCharsets.UTF_8);
Soweit
Ich weiß nicht, was das Problem war, aber es hat bei mir funktioniert, nachdem ich etwas geändert habe, an das ich mich nicht erinnern kann.
Roger
1
^^^ Sie mussten wahrscheinlich die Zielplattform in der IDE ändern. Wenn 1.6 Ihr letztes JDK war, als Sie die IDE installiert haben, hat es es wahrscheinlich als Standard ausgewählt und als Standard beibehalten, lange nachdem Sie sowohl die IDE als auch das JDK selbst aktualisiert hatten.
Bitbang3r
10

Diese Konstante ist verfügbar (ua als: UTF-16, US-ASCII, etc.) in der Klasse org.apache.commons.codec.CharEncodingals auch.

Alfredo Carrillo
quelle
9

Es gibt keine (zumindest in der Standard-Java-Bibliothek). Die Zeichensätze variieren von Plattform zu Plattform, daher gibt es in Java keine Standardliste.

Es gibt jedoch einige Bibliotheken von Drittanbietern, die diese Konstanten enthalten. Eine davon ist Guava (Google Core Libraries): http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Charsets.html

tskuzzy
quelle
Ich habe eine Sekunde gebraucht, um das zu verstehen ... Guavas Charsets-Konstanten sind (keine Überraschung) Charsets, keine Strings. InputStreamReader verfügt über einen anderen Konstruktor, der anstelle einer Zeichenfolge einen Zeichensatz verwendet. Wenn Sie die Zeichenfolge wirklich benötigen, ist dies z. B. Charsets.UTF_8.name ().
Ed Staub
1
Zeichensätze können von Plattform zu Plattform variieren, UTF-8 ist jedoch garantiert vorhanden.
Teer
3
Alle in definierten Zeichensätze StandardCharsetssind garantiert in jeder Java-Implementierung auf jeder Plattform vorhanden.
Krzysztof Krasoń
8

Sie können Charset.defaultCharset()API oder file.encodingEigenschaft verwenden.

Wenn Sie jedoch Ihre eigene Konstante möchten, müssen Sie diese selbst definieren.

paulsm4
quelle
11
Der Standardzeichensatz wird normalerweise durch die Einstellungen des Betriebssystems und des Gebietsschemas bestimmt. Ich glaube, es gibt keine Garantie dafür, dass er für mehrere Java-Aufrufe gleich bleibt. Dies ist also kein Ersatz für ein konstantes "utf-8".
Jörn Horstmann
6

In Java 1.7+

Verwenden Sie nicht die Zeichenfolge "UTF-8", sondern den CharsetTypparameter:

import java.nio.charset.StandardCharsets

...

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

Wenn Sie OkHttp für Java / Android verwenden, können Sie die folgende Konstante verwenden:

import com.squareup.okhttp.internal.Util;

Util.UTF_8; // Charset
Util.UTF_8.name(); // String
JJD
quelle
2
Es ist aus OkHttp entfernt, also ist der nächste Weg: Charset.forName("UTF-8").name()Wenn Sie Unterstützung für niedrigeres Android als API 19+ benötigen, können Sie Folgendes verwenden:StandardCharsets.UTF_8.name()
mtrakal
3

Konstante Definitionen für den Standard. Diese Zeichensätze sind garantiert bei jeder Implementierung der Java-Plattform verfügbar. seit 1.7

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

Die Klasse org.apache.commons.lang3.CharEncoding.UTF_8ist nach Einführung von Java 7 veraltetjava.nio.charset.StandardCharsets

  • @see JRE-Zeichencodierungsnamen
  • @ seit 2.1
  • @deprecated Java 7 führte {@link java.nio.charset.StandardCharsets} ein, das diese Konstanten als definiert
  • {@link Charset} Objekte. Verwenden Sie {@link Charset # name ()}, um die in dieser Klasse angegebenen Zeichenfolgenwerte abzurufen.
  • Diese Klasse wird in einer zukünftigen Version entfernt.
sendon1982
quelle