如何在 ZipEntry 中输入汉字?

How do I write chinese charactes in ZipEntry?

我想导出一个字符串(中文文本)到一个zip文件中的CSV文件。我在哪里需要将编码设置为UTF-8?或者我应该采取什么方法(基于下面的代码)在导出的 CSV 文件中显示中文字符?

这是我目前拥有的代码。

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ZipOutputStream zipOut = new ZipOutputStream(out, StandardCharsets.UTF_8)
        try {
            ZipEntry entry = new ZipEntry("chinese.csv");
            zipOut.putNextEntry(entry);
            zipOut.write("类型".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            zipOut.close();
            out.close();
        }

我在 CSV 文件中得到的不是“类”,而是“类型”。

getBytes() 方法是罪魁祸首之一,如果没有明确的字符集,它会采用您机器的默认字符集。截至 Java String 文档:

getBytes()
Encodes this String into a sequence of bytes using the platform's default charset, storing the result into a new byte array.

getBytes(string charsetName)
Encodes this String into a sequence of bytes using the given charset, storing the result into a new byte array.

此外,正如@Slaw 指出的那样,请确保您 compile (javac -encoding <encoding>) 您的文件使用与以下文件相同的编码:

-encoding Set the source file encoding name, such as EUC-JP and UTF-8. If -encoding is not specified, the platform default converter is used.

OP 中缺少对 closeEntry() 的调用。我将代码片段简化为我认为实现所需功能所必需的内容。

    try (FileOutputStream fileOut = new FileOutputStream("out.zip");
         ZipOutputStream zipOut = new ZipOutputStream(fileOut)) {
        zipOut.putNextEntry(new ZipEntry("chinese.csv"));
        zipOut.write("类型".getBytes("UTF-8"));
        zipOut.closeEntry();
    }

最后,正如@MichaelGantman 指出的那样,您可能想使用诸如十六进制编辑器之类的工具来检查编码中的内容,还要排除您查看结果文件的编辑器是否显示正确的 utf -8 以错误的方式。 "类" 在 utf-8 中是(十六进制)e7 b1 bb 在 utf-16 中(java 默认编码)它是 7c 7b

首先,您肯定需要将 zipOut.write("类型".getBytes()); 更改为 zipOut.write("类型".getBytes(StandardCharsets.UTF_8)); 此外,当您打开生成的 CSV 文件时,编辑器可能不知道内容是以 UTF-8 编码的。您可能需要告诉您的编辑器它是 UTF-8 编码。例如,在记事本中,您可以使用 "Save As" 选项保存文件并将编码更改为 UTF-8。此外,您的问题可能只是错误的显示问题,而不是实际编码。有一个开源 Java 库,它有一个实用程序,可以将任何字符串转换为 Unicode 序列,反之亦然。当我诊断各种与字符集相关的问题时,这个实用程序帮助了我很多次。这是代码所做的示例

result = "Hello World";
result = StringUnicodeEncoderDecoder.encodeStringToUnicodeSequence(result);
System.out.println(result);
result = StringUnicodeEncoderDecoder.decodeUnicodeSequenceToString(result);
System.out.println(result);

这段代码的输出是:

\u0048\u0065\u006c\u006c\u006f\u0020\u0057\u006f\u0072\u006c\u0064
Hello World

库可以在 Maven Central or at Github 找到它作为 maven artifact 并带有源代码和 javadoc

这是 class StringUnicodeEncoderDecoder

的 javadoc

我尝试了您的输入并得到了这个:

System.out.println(StringUnicodeEncoderDecoder.encodeStringToUnicodeSequence("类型"));
System.out.println(StringUnicodeEncoderDecoder.encodeStringToUnicodeSequence("类型"));

输出为:

\u7c7b\u578b
\u00e7\u00b1\u00bb\u00e5\u017e\u2039

所以看起来你确实丢失了信息,这不仅仅是显示问题