默认编码及其更改方式

5
默认情况下,CharacterString 使用UTF-16编码,但是在北美和大部分英语区域,使用UTF-8编码就足够了(因为它可以达到4个字节)。那么,如果我使用 InputStreamReader(InputStream),那么它会给我默认的UTF-16 char 编码吗?使用 InputStreamReader(InputStream, "UTF-8") 可以提供UTF-8编码,这对我的目的已经足够了。
如何在使用英语环境时自动设置JVM的默认编码为UTF-8?目的是通过使用8位方案而不是16位编码来改善 CharacterString 操作的性能(由于大多数ASCII都使用8位编码,并同时遵守Unicode标准)。
欢迎任何评论。谢谢!

3
我不是关于实际运行环境处理字符串的专家,但我认为除非您想创建自己的UTF-8字符串类的实现,否则无法更改它。请注意:通过在InputStreamReader构造函数中提供UTF-8,您不会改变Java本地(char)对象和字符串处理的方式,您只是改变输入数据的解析方式。不管您如何操作数据,在RAM中它都将被保持为UTF-16格式。 - initramfs
@CPUTerminator,感谢您的有用评论。您知道Java类文件的编码是什么吗?为了节省空间,它是UTF-8吗? - Ashley
类文件的“编码”可以通过不同的编译器选项进行更改。如果您使用的是集成开发环境(IDE),则应该在构建属性中某个地方提供此选项。 - initramfs
1
这不是效率问题。如果您的输入源以UTF-16编码,将字符集编码设置为UTF-8会导致解析的数据无效。同样,如果数据是UTF-8并且您将字符集编码设置为UTF-16,则会尝试将两个不同的字符读取为一个符号。输入流的字符编码参数不应该是可选的,因为它对数据的处理方式有很大影响,因此这里的基本问题不是效率,而是正确性。 - initramfs
啊!这进一步阐明了问题。所以在编码/解码字符集方面,更注重正确性而不是效率。我会记住的。再次感谢。 - Ashley
显示剩余3条评论
2个回答

4
Java中用于文本的内存数据类型char、Character和String都是UTF-16编码。总是。无条件的。
唯一可以更改的是Java从外部字节转换为内部字符的方式。没有办法将表示形式更改为UTF-8以节省空间。

@bmarguiles,谢谢。这很有帮助。转换仅用于解析数据,而不涉及其保存方式。 - Ashley
你知道Java类文件的编码是什么吗?为了节省空间,它是UTF-8吗? - Ashley
如果在JAVA中始终使用16位本地编码,那么为了提高效率,设置另一种编码的InputStreamReader是否有意义? 我认为在OutputStreamWriter上设置是有意义的,您怎么看? - Ashley
这与效率无关。读取器编码是必要的,以便告诉它磁盘上字节的格式。 - bmargulies

1
所以,如果我使用InputStreamReader(InputStream),那么它会给我默认的UTF-16字符编码吗?使用InputStreamReader(InputStream,"UTF-8")将提供UTF-8编码,这足以满足我的目的。在使用英语语言环境的同时,如何将JVM的默认编码自动设置为UTF-8?从InputstreamReader java DOC中可以看到:InputStreamReader使用的字符集可以通过名称指定,也可以明确给出,或者接受平台的默认字符集。就像当我尝试在我的平台上打印时使用reader.getEncoding();它打印UTF-8。Java通过在JVM启动时调用System.getProperty("file.encoding")来获取字符编码。因此,如果Java没有获取任何file.encoding属性,则对于所有实际目的,它使用UTF-8字符编码。但是要将编码设置为JVM实例,可以使用System.setProperty("file.encoding, "UTF-16")。

这里有一篇有关编程的有用文章,提供更多详细信息。


你提出了一个很好的观点。所以,如果我使用你的代码设置系统属性,那么我还需要使用InputStreamReader(InputStream,"UTF-8")吗?如果我在程序启动时调用System.setProperty("file.encoding","UTF-8")一次,那么它是否会成为该JVM实例的全局默认值? - Ashley
我还想问一下,设置了System.setProperty("file.encoding","UTF-8")之后,只有数据操作是UTF-8的,但实际上,无论如何,JAVA本身仍然会使用UTF-16。所以,如果我想使用UTF-32,那么我是否需要再次使用InputStreamReader(InputStream,"UTF-32")?我认为答案可能很明显,但如果您能确认一下,那就太好了。 - Ashley
1
1 Q: 不需要,如果您设置了系统属性,则不必在设置JVM实例的读取器构造函数中设置它。2 Q: 请检查此文章,我已经将其加为书签。 - Sage
1
据我所知,它是“UTF-8”。 - Sage
但是你可以从Java类文件的维基百科页面上得到正确的答案。 - Sage
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接