【问题标题】:String encoding conversion UTF-8 to SHIFT-JIS字符串编码转换 UTF-8 到 SHIFT-JIS
【发布时间】:2016-09-06 10:17:15
【问题描述】:

使用的变量:

  • JavaSE-6
  • 没有框架

鉴于ピーター・ジョーズ 的字符串输入以 UTF-8 编码,我在将所述字符串转换为 Shift-JIS 时遇到问题,而无需编写将上述数据保存到文件中。

  • 输入(UTF-8 编码):ピーター・ジョーンズ
  • 输出(SHIFT-JIS 编码):ピーター・ジョーンズ(要编码的 SHIFT-JIS)

我已经尝试过这段代码 sn-ps 关于如何将 UTF-8 字符串转换为 SHIFT-JIS:

  • stringToEncode.getBytes(Charset.forName("SHIFT-JIS"))
  • new String(unecodedString.getBytes("SHIFT-JIS"), "UTF-8")

两个代码 sn-ps 都返回此字符串输出:�s�[�^�[�E�W���[���Y(SHIFT-JIS 编码)

关于如何解决这个问题的任何想法?

【问题讨论】:

  • 我不了解全部情况。 Strings 在 java 中总是以 UTF-16 编码,任何其他编码要么保存在字节数组中,要么写入某种文件/控制台/......所以你从哪里得到你的输入和在哪里做你写/查看你的输出?
  • “转换而不写入文件”是什么意思?您希望 Shift-JIS 去哪里?
  • @piyushjaiswal 该建议已在上面列出,它产生了 �s�[�^�[�E�W���[���Y 的意外输出。
  • @CyrilHorad:请显示更多代码。它应该包括数据在转换之前来自哪里以及它要去哪里。

标签: java string encoding utf-8 character-encoding


【解决方案1】:

“MS932”而不是 Shift-JIS/SJIS 可能会成功。

【讨论】:

    【解决方案2】:

    在 Java 内部,字符串被实现为 UTF-16 代码单元的数组。但这是一个实现细节,有可能实现一个在内部使用不同编码的 JVM。

    (注意“encoding”、“charset”和 Charset 或多或少是同义词。)

    应将字符串视为 Unicode 代码点序列(即使在 Java 中它是 UTF-16 代码单元序列)。

    如果您的 Java 程序中有字符串,则不正确说它是“UTF-8 字符串”或“以 UTF-8 编码的字符串”。这没有任何意义,除非您谈论的是无关紧要的内部表示。

    如果您使用编码(例如 UTF-8 或 Shift-JIS)将其解码为字符串,则您可以拥有解码为字符串的字节序列。

    如果您使用编码(例如 UTF-8 或 Shift-JIS)对字符串进行编码,您也可以将字符串编码为字节序列。

    简而言之,编码或字符集是一对两个函数,“编码”和“解码”,这样:

    // String -> encode -> bytes
    byte[] bytes = string.getBytes(encoding);
    // or using Charset
    ByteBuffer byteBuffer = charset.encode(string);
    
    // bytes -> decode -> String
    String string = new String(bytes, encoding);
    // or using Charset
    String string = charset.decode(byteBuffer).toString();
    

    因此,如果您有一个使用 UTF-8 编码的 byte[]:

    byte[] utf8Bytes = "ピーター・ジョーズ".getBytes("UTF-8");
    // utf8Bytes now contains, in hexadecimal
    // e3 83 94  e3 83 bc  e3 82 bf   (ピ ー タ)
    // e3 83 bc  e3 83 bb  e3 82 b8   (ー ・ ジ)
    // e3 83 a7  e3 83 bc  e3 82 ba   (ョ ー ズ)
    

    你可以使用这些字节创建一个字符串:

    String string = new String(utf8Bytes, "UTF-8");
    // String now contains "ピーター・ジョーズ"
    

    然后您可以使用以下方法将该字符串编码为 Shift-JIS:

    byte[] shiftJisBytes = string.getBytes("Shift-JIS");
    // shiftJisBytes now contains, in hexadecimal
    // 83 73  81 5b  83 5e   (ピ ー タ)
    // 81 5b  81 45  83 57   (ー ・ ジ)
    // 83 87  81 5b  83 59   (ョ ー ズ)
    

    由于这些字节表示使用Shift-JIS 编码的字符串,因此尝试使用UTF-8 解码会产生垃圾:

    String garbage = new String(shiftJisBytes, "UTF-8")
    // String now contains "�s�[�^�[�E�W���[�Y"
    // � is the character decoded when given an invalid UTF-8 sequence
    // 83 73 81 5b 83 5e   (� s � [ � ^)
    // 81 5b 81 45 83 57   (� [ � E � W)
    // 83 87 81 5b 83 59   (� � � [ � Y)
    

    此外,请记住,如果您将字符串打印到输出,例如System.out,它将使用系统默认编码,该编码取决于系统将字符串转换为字节。看起来你的系统默认是UTF-8

    System.out.print(string);
    // equivalent to:
    System.out.write(string.getBytes(Charset.defaultCharset()));
    

    如果您的输出是例如 Windows 控制台,它会在将这些字节转换为字符串之前,使用很可能完全不同的编码(可能是 CP437CP850)将其呈现给您。

    这最后一部分可能会绊倒你。

    【讨论】:

      猜你喜欢
      • 2014-05-02
      • 1970-01-01
      • 2021-05-29
      • 2022-07-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多