Java中的八进制转义导致错误的字节值,编码问题?

Java中的八进制转义导致错误的字节值,编码问题?,java,linux,encoding,utf-8,Java,Linux,Encoding,Utf 8,根据本文档(,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)'\2

根据本文档(,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/C1.6.0_18的Linux上,我的默认编码是“UTF-8”

我的问题的背景是,我正在寻找一种方法来将八进制转义字符串从输入编码Cp1252转换为UTF-8。这失败了,因为八进制转义字符串转换为2字节。 有人知道为什么总是有一个额外的字节“c2”被添加到字符数组中吗?一个简单的计数显示,数组中只有一个字符

System.out.println("\222".toCharArray().length); // will result in "1"
谢谢你的提示

更新: 正如BalusC提到的,八进制转义值被解释为UTF-8值,这就产生了问题我不可能用其他编码读取此字符串。我是对的?如果我读取Cp1252编码的文件,我必须用正确的字符集声明InputReader的字符集,并对UTF-8进行编码,以处理读取的内容并将其保存为UTF-8。

没有指定编码的调用将使用平台默认编码to将字符转换为字节。由于
c2
是的两字节字符中的典型第一个字节,因此您显然使用UTF-8作为平台默认编码。如果希望获得CP1252字节,则需要在方法中明确指定


根据您的更新更新

只要这个值保存在源代码(UTF-8)中,我就不可能用其他编码读取这个字符串。我说的对吗

没错。您需要使用与文件保存时相同的编码来读取文件,否则可能会导致错误

如果我读取Cp1252编码的文件,我必须使用正确的字符集声明InputReader的字符集,并对UTF-8进行编码,以处理读取的内容并将其保存为UTF-8

只需使用
InputStreamReader
将文件读取为CP1252。当读取为字符(字符串)时,Java会将其隐式存储为Unicode(UTF-16)。您可以将数据视为Unicode。无需引入中间UTF-8文件步骤。如果要保存文件,请使用所需的字符集使用
OutputStreamWriter
,这可能与CP1252不同。请记住,字符集未包含的任何字符都将以
结尾

另见:

Java中的所有字符和字符串都是UTF-16。因此,您已经输入了控制字符并将其编码为UTF-8(当编码为UTF-8时,该字符需要两个字节)。编码为UTF-16以外的字符必须由字节数组表示

U+2019:' 我猜您打算对字符进行转码。在windows-1252中,该字符的字节值为
92
。我不想让您失望,但当编码为UTF-8时,它将最终成为多字节序列
E2 80 99


还要注意的是,在Java中,U+2019不能用八进制转义序列表示,因为它的值大于U+00FF。您必须使用Unicode转义序列
\u2019
。我写了一篇关于用不同语言进行代码转换和在Java源文件中编码的博文。

这导致输出为“3f”“。这不是我在中给出的八进制值。它是字节的十六进制表示形式,表示八进制
\222
表示的CP1252字符
92
是将文本字符串
222
从八进制转换为十六进制时的值。我认为您毕竟需要修改功能需求。可能您缺少了一个转换层(我打赌是字符编码本身)。请稍加更正:
3f
是一个
。打印它是因为在CP1252中无法表示Unicode字符
U+0092
。@axtavt:啊,我没有检查它。那是从头顶传来的。但事实上,CP1252不支持该字符。它是什么意思“将一个八进制转义字符串从输入编码CP1252转换为UTF-8”?显示输入和预期输出的示例。更新中的语句错误<代码>\222被视为Unicode码点
U+0092
,它不依赖于源编码。然后
String.getBytes()
返回默认编码中该代码点的表示形式。由于您的默认编码是
UTF-8
,因此您得到了
c2 92
,这是
UTF-8
U+0092
的表示形式。实际上,我读了您的一些博客文章,帮助您理解了字符编码的IHMO复杂主题。这就像一开始的regex,voodoo,但如果你深入挖掘,它会非常强大。谢谢
for (byte b : "\222".getBytes("cp1252")) {
     System.out.format("%02x ", b);
}