字符集问题本身是令人困惑和复杂的,但最重要的是,你必须记住你的字符集的确切名称。是“utf8”吗?或“utf - 8”?或者是“UTF-8”?当你在网上搜索代码样本时,你会看到上面所有的代码。为什么不直接将它们命名为常量并使用Charset.UTF8呢?
我认为我们可以做得更好……为什么不能直接访问保证可用的字符集?字符集。UTF8应该是对字符集的引用,而不是作为字符串的名称。这样我们就不用到处处理UnsupportedEncodingException了。
请注意,我还认为. net选择了一个更好的策略,在所有地方都默认为UTF-8。然后,它把“操作系统默认”编码属性命名为“encoding”,搞砸了。Default -这不是.NET本身的默认值:(
回到对Java字符集支持的咆哮——为什么没有一个用于FileWriter/FileReader的接受字符集的构造函数?基本上,由于这个限制,这些几乎是无用的类-你几乎总是需要一个InputStreamReader来处理fileinputstream或等效的输出:(
护士,护士,我的药呢?
编辑:在我看来,这并没有真正回答这个问题。真正的答案大概是“没有人想到”或者“有人认为这是个坏主意”。我强烈建议,提供名称或字符集的内部实用程序类避免在代码库中重复……或者你也可以用第一次写出这个答案时我们在谷歌处用的那个。(请注意,从Java 7开始,您只需使用StandardCharsets即可。)
对所问问题的简单回答是,可用的字符集字符串因平台而异。
然而,有六个是必须存在的,所以很久以前就可以为它们做常数了。我不知道为什么他们没有。
JDK 1.4 did a great thing by introducing the Charset type. At this point, they wouldn't have wanted to provide String constants anymore, since the goal is to get everyone using Charset instances. So why not provide the six standard Charset constants, then? I asked Martin Buchholz since he happens to be sitting right next to me, and he said there wasn't a really particularly great reason, except that at the time, things were still half-baked -- too few JDK APIs had been retrofitted to accept Charset, and of the ones that were, the Charset overloads usually performed slightly worse.
令人遗憾的是,直到JDK 1.6中,他们才最终完成了Charset重载的所有配置。而且这种性能落后的情况仍然存在(原因非常奇怪,我无法解释,但与安全性有关!)
长话短说——只要定义你自己的常量,或者使用Tony the Pony链接到的Guava的Charsets类(尽管这个库还没有真正发布)。
更新:在JDK 7中有一个StandardCharsets类。
编码API的当前状态还有待改进。Java 6 API的某些部分不接受Charset来代替字符串(在日志记录中,dom。ls, PrintStream;可能还有其他的)。对于标准库的不同部分,编码应该具有不同的规范名称,这并没有帮助。
我能理解事情是如何发展到现在这个地步的;我不确定我有什么好主意来解决它们。
题外话……
您可以在这里查找Sun的Java 6实现的名称。
对于UTF-8, java的规范值是“UTF-8”。nio和java的“UTF8”。Lang和java.io。该规范要求JRE支持的编码只有:US-ASCII;iso - 8859 - 1;utf - 8;UTF-16BE;UTF-16LE;utf - 16。
我很久以前就用UTF_8、ISO_8859_1和US_ASCII字符集常量定义了一个实用程序类。
此外,很久以前(2年多),我在new String(byte[], Charset)和new String(byte[], String charset_name)之间做了一个简单的性能测试,发现后一种实现要快得多。如果您仔细查看源代码,您会发现它们确实遵循了完全不同的路径。
出于这个原因,我在同一个类中包含了一个实用程序
public static String stringFromByteArray (
final byte[] array,
final Charset charset
)
{
try
{
return new String( array, charset.name( ) )
}
catch ( UnsupportedEncodingException ex )
{
// cannot happen
}
}
为什么String(byte[], Charset)构造函数不做同样的事情,打败了我。
两年后,Java 7的StandardCharsets现在定义了6个标准字符集的常量。
如果你被Java 5/6卡住了,你可以使用Guava的Charsets常量,就像Kevin Bourrillion和Jon Skeet建议的那样。
在Java 1.7中
进口java.nio.charset.StandardCharsets
例: StandardCharsets。UTF_8 StandardCharsets。US_ASCII
推荐文章
- malformedurlexception:没有协议
- 为什么字符集名称不是常量?
- Maven依赖项失败,出现501错误
- lambda表达式每次执行时都在堆上创建一个对象吗?
- 使用流相加bigdecimal
- Java抽象接口
- 无法识别的SSL消息,明文连接?异常
- 编码字符串为UTF-8
- 用于双值的assertEquals的delta或epsilon参数的含义
- 在Linux中安装Java SDK后,我可以在哪里找到它?
- Java等价于c#扩展方法
- 当使用JDBC连接到postgres时,是否可以指定模式?
- 是什么原因导致Eclipse中导入的Maven项目默认使用Java 1.5而不是Java 1.6,我如何确保它不使用?
- 是否有办法忽略单个FindBugs警告?
- 我是否需要同时关闭()FileReader和BufferedReader?