gpt4 book ai didi

java utf-8编码字符串中奇数个字符的字节变化

转载 作者:行者123 更新时间:2023-12-01 18:13:21 32 4
gpt4 key购买 nike

我有以下代码:

public static void main(String args[]) throws UnsupportedEncodingException {
System.setProperty("file.encoding", "gbk");

String name = "こんにちわ";
String copy = new String(name.getBytes("utf-8"));

byte[] b1 = name.getBytes("utf-8");
byte[] b2 = copy.getBytes();

System.out.println("b1: " + Arrays.toString(b1));
System.out.println("b2: " + Arrays.toString(b2));
}

控制台输出为:

b1: [-29, -127, -109, -29, -126, -109, -29, -127, -85, -29, -127, -95, -29, -126, -113]
b2: [-29, -127, -109, -29, -126, -109, -29, -127, -85, -29, -127, -95, -29, -126, 63]

请注意新字符串中的最后一个字节是不同的。

<小时/>

现在,如果我使用输入String name = "こんにち";(只有 4 个日语字符),它会更改为:

b1: [-29, -127, -109, -29, -126, -109, -29, -127, -85, -29, -127, -95]
b2: [-29, -127, -109, -29, -126, -109, -29, -127, -85, -29, -127, -95]

这次字节完全相同。

<小时/>

我在 Windows 上使用 java jdk1.6.0_45。默认字符集是gbk。我是否遇到了一些编码限制?

最佳答案

基本上,程序的前四行相当于:

    String name = "こんにちわ";
byte[] b1 = name.getBytes("utf-8");

String a = new String( name.getBytes("utf-8"), "gbk" );
byte[] b2 = a.getBytes("gbk");

也就是说,您正在获取一个字节数组 (b1),它是日语字符串的 UTF-8 表示形式,并告诉 Java“此字节数组采用 GBK 编码,将其转换为文本”。

这不起作用,如果您打印 a 字符串,您会发现它不会打印日语文本,而是打印一些中文乱码 - 加上替换字符(“�”)结束。

在内部,Java 字符串以 UTF-16 编码。但是当您在字节数组之间进行转换时,您必须指定编码。编码彼此不同,并且可能使用相同的字节值或字节值序列来表示完全不同的字符。

在这种情况下,UTF-8 中的某些字节序列在 GBK 中是不合法的,因此 Java 会为您将它们替换为替换字符。

如果您想从 b1 创建一个新字符串,并且它仍然是 こんにちわ,您需要创建 a 告诉 Java字节采用 UTF-8 格式。

    String a = new String( name.getBytes("utf-8"), "utf-8" );

然后,您的 a 将等于 name

然后,如果您执行a.getBytes(),您将获得以GBK 表示该字符串的字节。它与 b1不同,因为它采用不同的编码。要获得相同的数组,您需要使用相同的编码(a.getBytes("utf-8"))。

  • 尽量不要依赖 Java 的默认字符集。当您从字符串获取字节以及将字节转换为字符串时,请始终指定确切的字符集。
  • 不同的字符集会为同一字符串生成不同的字节数组。
  • 不带字符集参数的
  • getBytes()String(byte[]) 不会为您提供 String 之下的真实字节序列。它们使用 JVM 的默认字符集 - 在您的例子中为 GBK。

关于java utf-8编码字符串中奇数个字符的字节变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31244584/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com