【问题标题】:Java application failing on special charactersJava 应用程序在特殊字符上失败
【发布时间】:2008-10-30 16:53:44
【问题描述】:

我正在开发的应用程序从文件中读取信息以填充数据库。文件中的某些字符是非英语字符,例如带重音的法语字符。

该应用程序在 Windows 中运行良好,但在我们的 Solaris 机器上它无法识别特殊字符并引发异常。例如,当它遇到“Gérer”中的重音 e 时,它​​会说:-

 遇到: "\u0161" (353), after: "\'G\u00c3\u00a9rer les mod\u00c3"

(从我们的应用程序抛出的异常)

我怀疑为了阻止这种情况发生,我需要更改 JVM 的 file.encoding 属性。我尝试通过 System.setProperty() 执行此操作,但并没有阻止错误的发生。

对我能做什么有什么建议吗?我正在考虑将 /etc/default/init 中的 solaris 平台的基本语言环境设置为 UTF-8。有人认为这可能会有所帮助吗?

非常感谢任何想法。

【问题讨论】:

    标签: java character-encoding solaris locale special-characters


    【解决方案1】:

    这看起来像是native2ascii 使用错误参数转换的文件。为了演示,创建一个包含内容的文件

    Gérer les modÚ
    

    并将其保存为“a.txt”,编码为 UTF-8。然后运行这个命令:

    native2ascii -encoding windows-1252 a.txt b.txt
    

    打开新文件,你应该会看到:

    G\u00c3\u00a9rer les mod\u00c3\u0161
    

    现在反转过程,但这次指定 ISO-8859-1:

    native2ascii -reverse -encoding ISO-8859-1 b.txt c.txt
    

    以 UTF-8 格式读取新文件,您应该会看到:

    Gérer les modÀ\u0161
    

    它可以恢复“é”,但会阻塞“Ú”,就像您的应用一样。

    我不知道您的应用程序出了什么问题,但我很确定对 native2ascii 的错误使用是其中的一部分。这可能是让应用程序使用系统默认编码的结果。当你保存文本时,你应该总是指定编码,无论是文件还是数据库或什么——永远不要让它默认。如果您没有充分的理由选择其他内容,请使用 UTF-8。

    【讨论】:

      【解决方案2】:

      尝试使用

      java -Dfile.encoding=UTF-8 ...
      

      在两个系统中启动应用程序时。

      解决问题的另一种方法是将两个系统的编码都更改为 UTF-8,但我更喜欢第一个选项(对系统的干扰较小)。

      编辑:

      在stackoverflow上查看这个答案,它可能会有所帮助:

      Changing the default encoding for String(byte[])

      【讨论】:

      • 是的,我以前见过。我唯一的问题是我找不到 java 命令实际运行的位置。这是因为程序使用 Ant 来运行代码。感谢您的回答,尽管我会尝试使用它。
      【解决方案3】:

      在读取和写入特定文本数据时指定字符编码,而不是设置系统范围的字符编码,可能会更容易、更健壮。您的应用程序如何读取文件?所有 Java I/O 包读取器和写入器都支持传入字符编码名称,以便在从字节读取/写入文本时使用。如果您不指定一个,它将使用平台默认编码,就像您可能遇到的那样。

      有些数据库在它们可以接受的文本编码方面令人惊讶地受到限制。如果您的 Java 应用程序以适当的编码将文件作为文本读取,那么它可以根据需要将其输出到数据库。如果您的数据库不支持其字符重复包含您拥有的非 ASCII 字符的任何编码,那么您可能需要先将非英文文本编码为 UTF-8 字节,然后 Base64 将这些字节编码为 ASCII 文本.

      PS:出于您所看到的原因,切勿使用没有字符编码参数的String.getBytes()

      【讨论】:

        【解决方案4】:

        我通过运行命令设法克服了这个错误

        导出 LC_ALL='en_GB.UTF-8'

        此命令设置我所在的 shell 的语言环境。这将所有 LC_ 环境变量设置为 Unicode 文件编码。

        非常感谢您提出的所有建议。

        【讨论】:

          【解决方案5】:

          你也可以在命令行设置编码,比如java -Dfile.encoding=utf-8

          【讨论】:

            【解决方案6】:

            我认为我们需要更多信息才能帮助您解决问题:

            1. 您到底遇到了什么异常,发生时您调用了哪个方法。
            2. 输入文件的编码是什么? UTF8? UTF16/Unicode? ISO8859-1?

            如果您能给我们提供相关的代码sn-ps,也会很有帮助。

            另外,我想指出几点:

            1. 问题不是在“é”处出现,而是在稍后出现。
            2. 听起来字符编码可能在您的应用程序中的某个地方进行了硬编码。

            【讨论】:

            • 该异常是在我们的软件中定义的,当解析器尝试了所有操作但仍然无法识别字符时会抛出该异常。它使用的编码是系统默认的,默认设置为 en_GB.ISO8859-15。我正在寻找一种方法来强制应用程序读取 UTF8
            【解决方案7】:

            此外,您可能需要验证是否安装了支持 UTF-8(SUNWeulux、SUNWeuluf 等)的操作系统包。

            【讨论】:

              【解决方案8】:

              Java 在读写文件时使用操作系统的默认编码。现在,一个人永远不应该依赖它。明确指定编码始终是一个好习惯。

              在 Java 中,您可以使用以下方式进行读写:

              阅读:

              BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(inputPath),"UTF-8"));
              

              写作:

              PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputPath), "UTF-8")));
              

              【讨论】:

                猜你喜欢
                • 2021-02-04
                • 1970-01-01
                • 1970-01-01
                • 2021-12-13
                • 2013-10-17
                • 2015-09-14
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多