【问题标题】:Encoding cp-1252 as utf-8?将 cp-1252 编码为 utf-8?
【发布时间】:2012-08-16 06:01:11
【问题描述】:

我正在尝试编写一个 Java 应用程序,该应用程序将在 linux 服务器上运行,但它会使用 cp-1252 作为字符集来处理在旧版 Windows 机器上生成的文件。有没有办法将这些文件编码为 utf-8 而不是生成的 cp-1252?

【问题讨论】:

  • 这个问题在发布时无法回答......这完全取决于生成这些文件的内容(您没有告诉我们)。如果是 Excel 2007,那么答案是否定的。
  • 但是,如果编码参数正确,Java 应该能够很好地处理这些 Windows 文件。
  • 谢谢@theglauber (+2) - 你能解释一下为什么 Excel 2007 会成为破坏者吗?另外,你能举一个正确编码参数的例子吗?再次感谢!
  • 只是从经验和挫折中说出来。您无法在 Excel 2007 中指定 csv 文件的编码。在 Java 中,您将使用构建在 FileInputStream 之上的具有正确编码(“Windows-1252”)的 InputStreamReader。
  • 谢谢@theglauber - 请在 Eric Grunzke 的回答下方查看我的评论。您的上述建议是否解决了我的问题?

标签: java linux utf-8 character-encoding cp1252


【解决方案1】:

如果文件名和内容有问题,解决问题的最简单方法是在 Linux 机器上将locale 设置为基于ISO-8859-1 而不是UTF-8。您可以使用locale -a 列出可用的语言环境。例如,如果您有 en_US.iso88591,您可以使用:

export LANG=en_US.iso88591

这样,Java 将使用 ISO-8859-1 作为文件名,这可能已经足够了。要运行 Java 程序,您仍然需要设置 file.encoding 系统属性:

java -Dfile.encoding=cp1252 -cp foo.jar:bar.jar blablabla

如果没有可用的 ISO-8859-1 语言环境,您可以使用localedef 生成一个。安装它需要root访问权限。事实上,您可以生成一个使用 CP-1252 的语言环境,如果它在您的系统上可用的话。例如:

sudo localedef -f CP1252 -i en_US en_US.cp1252
export LANG=en_US.cp1252

这样,Java 应该默认对所有 I/O 使用 CP1252,包括文件名。

在此处进一步扩展:http://jonisalonen.com/2012/java-and-file-names-with-invalid-characters/

【讨论】:

    【解决方案2】:

    您可以使用任何您希望的编码方式读取和写入文本数据。这是一个快速的代码示例:

      public static void main(String[] args) throws Exception
      {
        // List all supported encodings
        for (String cs : Charset.availableCharsets().keySet())
          System.out.println(cs);
    
        File file = new File("SomeWindowsFile.txt");
        StringBuilder builder = new StringBuilder();
    
        // Construct a reader for a specific encoding
        Reader reader = new InputStreamReader(new FileInputStream(file), "windows-1252");
        while (reader.ready())
        {
          builder.append(reader.read());
        }
        reader.close();
    
        String string = builder.toString();
    
        // Construct a writer for a specific encoding
        Writer writer = new OutputStreamWriter(new FileOutputStream(file), "UTF8");
        writer.write(string);
        writer.flush();
        writer.close();
      }
    

    如果读取时仍然“窒息”,请查看您是否可以验证原始编码是否是您认为的那样。在这种情况下,我指定了 windows-1252,它是 cp-1252 的 java 字符串。

    【讨论】:

    • 感谢@Eric Grunzke (+1) - 问题的一部分是文件名本身(即SomeWindowsFile.txt)有时包含一个CP-1252 字符,导致Java Reader 阻塞。所以真正的问题是:如何读取文件名因“非法”字符而导致 Java 阻塞的文件?再次感谢!
    • 您最好希望它在 Windows 上运行,因为 CP-1252 很可能不会成为其他上下文中的默认文本文件编码。最好使用new InputStreamReader(new FileInputStream(file, "Win1252"))
    • @4herpsand7derpsago 如何让Reader 窒息?你能用SSCCE演示吗?
    • 我更新了代码示例以展示如何在阅读器中强制编码。 Veer 的问题是一个很好的问题:我很好奇您所说的“窒息”是什么意思,以及这是否能解决这个问题。
    • 对不起,我误读了您的评论。您遇到了文件 name 中的异常字符问题,而不是文件 data 中的问题。那更棘手。我建议尝试 Joni 的设置 -Dfile.encoding=windows-1252 的解决方案。此外,您可以尝试 new File("the/parent/dir").list() 并查看 Java 是否以不同的方式解释文件名。
    猜你喜欢
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多