Java UTF-8 编码产生不正确的输出

标签 java string encoding utf-8

在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 个字节

最佳答案

我怀疑问题在于您在 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
        }
    }
}

关于Java UTF-8 编码产生不正确的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22120246/

相关文章:

java - 如何在字符串数组中查找给定字符串的索引?

尽管 HTTP 代码 200,PHP cURL 返回空 header 和正文

xml - BeautifulSoup 不使用 utf-8 以外的其他编码解析 xml

c# - 如何将字符串转换为 HTML 安全字符串

java - onResponse返回变量或抛出异常Retrofit 2.0

java - Caused by : java. lang.IllegalStateException: 请求聚合时必须指定有效的分桶策略

java - 来自 JOptionPane 的返回值表示选择的按钮

C: char* 数组中的最后一个元素重写所有数组条目

R 多个模式的精确匹配

java - 获取剪贴板字符串编码 (java)