【问题标题】:Java UTF-8 encoding produces incorrect outputJava UTF-8 编码产生不正确的输出
【发布时间】:2014-04-02 22:27:42
【问题描述】:

在 Java 中,我一直在尝试使用 UTF-8 编码将字符串写入文件,该文件稍后将被另一个用不同编程语言编写的程序读取。这样做时,我注意到将字符串编码为字节数组时创建的字节似乎没有正确的字节值。

我将问题缩小到符号“£”,它在编码为 UTF-8 时似乎会产生不正确的字节

byte[] byteArray = "£".getBytes(Charset.forName("UTF-8"));

// Print out the Byte Array of the UTF-8 converted string
// Upcast byte values to print the bytes as unsigned
for (byte signedByte : byteArray) {
  System.out.print((signedByte & 0xFF) + " ");
} 

这输出 6 个字节,十进制值:239 190 130 239 189 163,十六进制为:ef be 82 ef bd a3

http://www.utf8-chartable.de/ 但是表示“£”的十六进制值是:c2 a3, 那么输出应该是:194 163

其他字符串在编码为 UTF-8 时似乎会产生正确的字节,所以我想知道为什么 Java 会为“£”产生这 6 个字节,以及我应该如何使用 UTF-正确地将字符串转换为字节数组8位编码

我也试过

OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8");
out.write("£");
out.close();

但这产生了相同的 6 个字节

【问题讨论】:

  • 我复制并粘贴了您的代码,它按预期生成 194 163。我怀疑您实际上是在对单个 £ 字符进行编码以获得 6 个字节。您使用的是哪个平台和 JDK?您确定执行的代码是您发布的代码吗?
  • 我的完整代码是 pastebin.com/uV3m6Pri 我正在使用 jdk1.7.0_51 并且正在运行 windows 7 64bit
  • @user3369258:但是你的源文件是什么编码的,你是怎么编译的?尝试在您的代码中将每次出现的£ 替换为\u00a3,我相信您会发现它有效。

标签: java string encoding utf-8


【解决方案1】:

我怀疑问题在于您在 Java 代码中使用了一个字符串文字,而该编辑器使用一种编码将其写出 - 但是您在 编译 时没有指定相同的编码。换句话说,我怀疑您的 "£" 字符串实际上根本不是一个井号。

这应该很容易验证。例如:

char[] chars = "£".toCharArray();
for (char c : chars) {
    System.out.println((int) c);
}

要排除这个等式,您可以使用 Unicode 转义序列使用纯 ASCII 表示来指定字符串:

String pound = "\u00a3";
// Now encode as before

我相信你会得到正确的字节。例如:

import java.nio.charset.Charset;

class Test {
    public static void main(String[] args) throws Exception {
        String pound = "\u00a3";
        byte[] bytes = pound.getBytes(Charset.forName("UTF-8"));
        for (byte b : bytes) {
            System.out.println(b & 0xff); // 194, 163
        }
    }
}

【讨论】:

  • 谢谢,使用 Unicode 转义序列写出来是有效的!运行输出的第一个代码块:65410 65379
  • 很好的答案!没想到文件和编译器编码不匹配。
  • 要添加到此解决方案中,我相信导致 Jon Skeet 描述的问题的原因是因为我的系统区域设置实际上是日语,这将我的默认文件编码设置为“MS932”,将 defaultCharset 设置为“windows -31j”而不是“UTF-8”。通过将环境变量 JAVA_TOOL_OPTIONS 的值更改为 -Dfile.encoding=UTF8,我设法让 JVM 以默认编码设置为 UTF-8 而不是系统默认值启动,并且程序在不使用 Unicode 转义序列的情况下工作!查看stackoverflow.com/questions/361975/…
猜你喜欢
  • 1970-01-01
  • 2018-10-25
  • 2019-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-13
  • 2016-02-29
  • 2016-02-01
相关资源
最近更新 更多