Java中的linux八进制转义导致错误的字节值,编码问题?
根据本文档(http://java.sun.com/docs/books/jls/third_edition/html/lexical.html,3.10.6),八进制字符将转换为unicode字符。现在我遇到了一个问题,下面的代码将导致一个包含错误信息的2字节Unicode字符
for (byte b : "\222".getBytes()) {
System.out.format("%02x ", b);
}
结果是“c2 92”。我只表达了“92”,因为这是从222八进制到十六进制(92)的转换值。 如果我用一个字符来测试,字节信息是正确的
System.out.format("%02x ", (byte)'\222');
结果是“92”代表一个字节” 在使用Java/c 1.6.0_18的Linux上,我的默认编码是“UTF-8”
我问题的背景是,我正在寻找一种方法,将八进制转义字符串从输入编码Cp1252转换为UTF-8。由于将八进制转义字符串转换为2字节,此操作失败。 有人知道为什么总是有一个额外的字节“c2”被添加到字符数组中吗?一个简单的计数显示,数组中只有一个字符
System.out.println("\222".toCharArray().length); // will result in "1"
谢谢你的提示
更新: 正如BalusC提到的,八进制转义值被解释为UTF-8值,这就产生了问题。只要这个值保存在源代码(UTF-8)中,我就不可能用其他编码读取这个字符串。我说得对吗?如果我读取Cp1252编码的文件,我必须用正确的字符集声明InputReader的字符集,并对UTF-8进行编码,以处理读取的内容并将其保存为UTF-8
# 1 楼答案
没有指定编码的^{} 调用将使用平台默认编码将字符转换为字节。由于} 方法中显式指定
c2
是multibyte UTF-8 sequence的两字节字符的典型第一个字节,所以显然使用UTF-8作为平台默认编码。如果想要获取CP1252字节,那么需要在^{根据您的更新更新:
没错。您需要使用与文件保存时相同的编码来读取文件,否则可能会以mojibake结束
只需使用
InputStreamReader
将文件读取为CP1252即可。当读取为字符(字符串)时,Java会将其隐式存储为Unicode(UTF-16)。可以将数据视为Unicode。无需引入中间UTF-8文件步骤。如果要保存文件,请将OutputStreamWriter
与所需的字符集一起使用,这可能与CP1252不同。请记住,任何字符集未包含的字符都将以?
结尾另请参见: