在Java中从哪里获取“ UTF-8”字符串文字?


489

我试图在这段代码中使用常量而不是字符串文字:

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

"UTF-8"出现在代码中的频率较高,而最好是引用某些static final变量。您知道我在JDK哪里可以找到这样的变量吗?

顺便说一句,顺便说一句,这样的常数是不好的设计:公共静态文字...不是数据复制的解决方案



1
注意:如果您已经在使用Java 7,请Files.newBufferedWriter(Path path, Charset cs)从NIO 使用。
富兰克林于

Answers:


834

在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
btw .displayName()也将起作用,除非它按预期被本地化了。
罗杰

36
您根本不需要打电话name()。您可以将Charset对象直接传递给InputStreamReader构造函数。
Natix 2014年

6
还有其他的lib确实需要一个lib String,也许是由于遗留原因。在这种情况下,我会保留一个Charset对象,通常是从派生的StandardCharsets,并name()在需要时使用。
Magnilex

134

现在,我使用commons-lang中的org.apache.commons.lang3.CharEncoding.UTF_8常量。


4
对于使用Lang 3.0的用户:org.apache.commons.lang3.CharEncoding.UTF_8。(请注意“ lang3”)。
罗素席尔瓦

24
如果您使用的是Java 1.7,请参阅下面的@Roger答案,因为它是标准库的一部分。
Drew Stephens

2
PS“下面的@Roger的答案”现在是上面的 @Roger的答案。☝
加里·

自从Java 7引入java.nio.charset.StandardCharsets以来,该类已弃用
sendon1982

66

谷歌番石榴库(我会强烈建议,无论如何,如果你用Java做的工作)有一个Charsets与像静态字段级的Charsets.UTF_8Charsets.UTF_16

从Java 7开始,您应该只使用java.nio.charset.StandardCharsets可比较的常量。

请注意,这些常量不是字符串,而是实际Charset实例。所有使用字符集名称的标准API都有一个重载,该重载带有Charset您应该使用的对象。


3
因此,应该是Charsets.UTF_8.name()吗?
2013年

1
@kilaka是的,因为name()是最终的,而getDisplayName()不是,所以请使用name()而不是getDisplayName()
RKumsher 2014年

3
@Buffalo:请再次阅读我的答案:建议java.nio.charset.StandardCharsets尽可能使用,这不是第三方代码。此外,番石榴字符集的定义不是“不断修改”的,并且AFAIK从未破坏过向后兼容性,因此我认为您的批评是没有根据的。
丹尼尔·普里登

2
@布法罗:可能是这样,但我怀疑您的问题与Charsets全班有关。如果您想抱怨番石榴,那很好,但这不是这些抱怨的地方。
丹尼尔·普赖登

1
请不要包含多兆字节的库来获取一个字符串常量。
杰弗里·布拉特曼

50

如果该页面出现在某人的Web搜索中,则从Java 1.7开始,您现在可以使用java.nio.charset.StandardCharsets来访问标准字符集的常量定义。


我一直在尝试使用它,但是它似乎没有用。'Charset.defaultCharset());' 在包含“ java.nio.charset。*”之后似乎可以正常工作,但是当我尝试使用“ File.readAllLines”时似乎无法显式地引用UTF8。
罗杰

1
@Roger似乎是什么问题?据我Files.readAllLines(Paths.get("path-to-some-file"), StandardCharsets.UTF_8);
所知,

我不知道问题出在哪里,但是在更改了我不记得的内容后,它对我有用。
罗杰

1
^^^您可能必须在IDE中更改目标平台。如果1.6是您在安装IDE时最新的JDK,则很可能在您就地更新了IDE和JDK本身之后很长一段时间就将其选择为默认值,并将其保留为默认值。
Bitbang3r


9

没有(至少在标准Java库中)。字符集因平台而异,因此Java中没有标准的字符集列表。

虽然有些第三方库包含这些常量。其中之一是Guava(Google核心库):http : //guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Charsets.html


我花了一秒钟的时间来理解这一点... Guava的Charsets常量是(毫不奇怪)Charsets,而不是Strings。InputStreamReader有另一个采用字符集而不是字符串的构造函数。如果您确实需要该字符串,则为例如Charsets.UTF_8.name()。
Ed Staub,

1
字符集的确因平台而异,但是可以保证存在UTF-8。
tar

3
StandardCharsets确保定义的所有字符集都存在于每个平台的每个Java实现中。
KrzysztofKrasoń'16

8

您可以使用Charset.defaultCharset()API或file.encoding属性。

但是,如果您想要自己的常量,则需要自己定义。


11
默认字符集通常由操作系统和语言环境设置确定,我认为不能保证多个Java调用都保持相同。因此,这不能替代常量分隔的“ utf-8”。
约恩·霍斯特曼(JörnHorstmann)

6

在Java 1.7+中

不要使用“ UTF-8”字符串,而应使用Charsettype参数:

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()当您需要支持低于API 19+的Android时,否则可以使用: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 7后不推荐使用该类java.nio.charset.StandardCharsets

  • @see JRE字符编码名称
  • @自2.1起
  • @deprecated Java 7引入了{@link java.nio.charset.StandardCharsets},它将这些常量定义为
  • {@link Charset}对象。使用{@link Charset#name()}获取此类中提供的字符串值。
  • 此类将在将来的版本中删除。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.