Skąd wziąć dosłowny ciąg „UTF-8” w Javie?

489

Próbuję użyć stałej zamiast literału ciągu w tym fragmencie kodu:

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

"UTF-8"pojawia się w kodzie dość często i znacznie lepiej byłoby odwoływać się do jakiejś static finalzmiennej. Czy wiesz, gdzie mogę znaleźć taką zmienną w JDK?

BTW, z drugiej strony, takie stałe są złym projektem: Publiczne literały statyczne ... nie są rozwiązaniem dla powielania danych

yegor256
źródło
11
Zobacz to pytanie .
highlycaffeinated
1
Uwaga: jeśli korzystasz już z Java 7, skorzystaj Files.newBufferedWriter(Path path, Charset cs)z NIO.
Franklin Yu,

Odpowiedzi:

835

W Javie 1.7+ java.nio.charset.StandardCharsets definiuje stałe do Charsetwłączenia UTF_8.

import java.nio.charset.StandardCharsets;

...

StandardCharsets.UTF_8.name();

Dla systemu Android: minSdk 19

zrozumiałem
źródło
3
używasz na tym .toString ()?
Matt Broekhuis
54
.toString()będzie działać, ale właściwa jest funkcja .name(). 99,9% toString nie jest odpowiedzią.
Roger,
1
btw .displayName()będzie również działać, chyba że zostanie zastąpione lokalizacją zgodnie z przeznaczeniem.
Roger,
36
Tak naprawdę wcale nie musisz dzwonić name(). Możesz bezpośrednio przekazać Charsetobiekt do InputStreamReaderkonstruktora.
Natix,
6
Są też inne biblioteki, które wymagają String, być może z powodów historycznych. W takich przypadkach trzymam w Charsetpobliżu obiekt, zwykle pochodzący z niego StandardCharsetsi używam go w name()razie potrzeby.
Magnilex,
134

Teraz używam org.apache.commons.lang3.CharEncoding.UTF_8stałej z commons-lang .

yegor256
źródło
4
Dla osób korzystających Lang 3.0: org.apache.commons.lang3.CharEncoding.UTF_8. (Uwaga „lang3”).
Russell Silva,
24
Jeśli używasz Java 1.7, zobacz odpowiedź @ Rogera poniżej, ponieważ jest ona częścią standardowej biblioteki.
Drew Stephens,
2
PS „Odpowiedź @ Rogera poniżej” jest teraz odpowiedzią @ Rogera powyżej . ☝
Gary S.
Ta klasa jest przestarzała, ponieważ Java 7 wprowadza java.nio.charset.StandardCharsets
sendon1982
66

Biblioteka Google Guava (którą i tak bardzo polecam, jeśli pracujesz w Javie) maCharsets klasę z statycznych pól takich jak Charsets.UTF_8, Charsets.UTF_16itp

Od wersji Java 7 java.nio.charset.StandardCharsetszamiast tego powinieneś używać zamiast porównywalnych stałych.

Zauważ, że te stałe nie są ciągami, są rzeczywistymi Charsetinstancjami. Wszystkie standardowe interfejsy API, które przyjmują nazwę zestawu znaków, mają również przeciążenie, które zabiera Charsetobiekt, którego należy użyć zamiast tego.

Daniel Pryden
źródło
3
Czy zatem powinna być Charsets.UTF_8.name ()?
AlikElzin-kilaka
1
@kilaka Tak, użyj name () zamiast getDisplayName (), ponieważ name () jest ostateczny, a getDisplayName () nie jest
RKumsher
3
@Buffalo: Przeczytaj ponownie moją odpowiedź: zaleca się, java.nio.charset.StandardCharsetsjeśli to możliwe, użycie , które nie jest kodem strony trzeciej. Ponadto definicje zestawów znaków Guava nie są „ciągle modyfikowane”, a AFAIK nigdy nie zerwała kompatybilności wstecznej, więc nie sądzę, aby twoja krytyka była uzasadniona.
Daniel Pryden
2
@Buffalo: Tak może być, ale wątpię, żeby twoje problemy miały coś wspólnego z Charsetsklasą. Jeśli chcesz narzekać na Guava, to w porządku, ale to nie jest miejsce na te skargi.
Daniel Pryden
1
Nie dołączaj biblioteki wielobajtowej, aby uzyskać stały ciąg znaków.
Jeffrey Blattman,
50

W przypadku pojawienia się tej strony podczas wyszukiwania w sieci, od wersji Java 1.7 możesz teraz używać java.nio.charset.StandardCharsets, aby uzyskać dostęp do stałych definicji standardowych zestawów znaków.

Cosjav
źródło
Próbowałem tego użyć, ale wydaje się, że to nie działa. „Charset.defaultCharset ());” wydaje się działać po dołączeniu „java.nio.charset. *”, ale nie mogę wyraźnie odwoływać się do UTF8, gdy próbuję użyć „File.readAllLines”.
Roger
1
@Roger Na czym polega problem? Z tego, co widzę, możesz po prostu zadzwonić:Files.readAllLines(Paths.get("path-to-some-file"), StandardCharsets.UTF_8);
cosjav
Nie wiem, na czym polegał problem, ale zadziałało to po zmianie czegoś, czego nie pamiętam.
Roger
1
^^^ Prawdopodobnie musiałeś zmienić platformę docelową w IDE. Jeśli 1.6 był twoim najnowszym JDK podczas instalowania IDE, prawdopodobnie wybrał go jako domyślny i zachował jako domyślny długo po zaktualizowaniu zarówno IDE, jak i samego JDK w miejscu.
Bitbang3r,
10

Stała ta dostępna jest (między innymi jak: UTF-16, US-ASCII, itd.) W klasie org.apache.commons.codec.CharEncoding, jak również.

Alfredo Carrillo
źródło
9

Nie ma ich (przynajmniej w standardowej bibliotece Java). Zestawy znaków różnią się w zależności od platformy, więc w Javie nie ma standardowej listy.

Istnieją jednak biblioteki innych firm, które zawierają te stałe. Jedną z nich jest Guava (podstawowe biblioteki Google): http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Charsets.html

tskuzzy
źródło
Zajęło mi to sekundę, aby złapać się tego ... Stałe zestawy znaków Guawy to (nie jest zaskoczeniem) zestawy znaków, a nie smyczki. InputStreamReader ma inny konstruktor, który pobiera zestaw znaków zamiast łańcucha. Jeśli naprawdę potrzebujesz ciągu, jest to np. Charsets.UTF_8.name ().
Ed Staub,
1
Zestawy znaków mogą się różnić w zależności od platformy, ale na pewno istnieje UTF-8.
tar
3
Wszystkie zdefiniowane zestawy znaków StandardCharsetssą gwarantowane w każdej implementacji Java na każdej platformie.
Krzysztof Krasoń,
8

Możesz użyć Charset.defaultCharset()API lubfile.encoding właściwości.

Ale jeśli chcesz mieć swoją stałą, musisz ją zdefiniować sam.

paulsm4
źródło
11
Domyślny zestaw znaków jest zwykle określany przez system operacyjny i ustawienia regionalne, nie sądzę, że istnieje jakakolwiek gwarancja, że ​​pozostanie taki sam dla wielu wywołań Java. Nie zastępuje to ciągłego rozdzielania „utf-8”.
Jörn Horstmann
6

W Javie 1.7+

Nie używaj ciągu „UTF-8”, zamiast tego użyj Charsetparametru type:

import java.nio.charset.StandardCharsets

...

new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8);
Mostafa Vatanpour
źródło
4

Jeśli używasz OkHttp dla Java / Android, możesz użyć następującej stałej:

import com.squareup.okhttp.internal.Util;

Util.UTF_8; // Charset
Util.UTF_8.name(); // String
JJD
źródło
2
jest usunięty z OkHttp, więc następnym sposobem jest: Charset.forName("UTF-8").name()kiedy potrzebujesz wsparcia dla Androida niższego niż API 19+, w przeciwnym razie możesz użyć:StandardCharsets.UTF_8.name()
mtrakal
3

Stałe definicje normy. Te zestawy znaków są z pewnością dostępne na każdej implementacji platformy Java. od 1.7

 package java.nio.charset;
 Charset utf8 = StandardCharsets.UTF_8;
Vazgen Torosyan
źródło
0

Klasa org.apache.commons.lang3.CharEncoding.UTF_8jest przestarzała po wprowadzeniu Java 7java.nio.charset.StandardCharsets

  • @ Zobacz nazwy kodujące znaki JRE
  • @ od 2.1
  • @deprecated Java 7 wprowadził {@link java.nio.charset.StandardCharsets}, który definiuje te stałe jako
  • {@link Charset} obiektów. Użyj {@link Charset # name ()}, aby uzyskać wartości ciągów podane w tej klasie.
  • Ta klasa zostanie usunięta w przyszłej wersji.
sendon1982
źródło