【问题标题】:How to compile a java source file which is encoded as "UTF-8"?如何编译编码为“UTF-8”的java源文件?
【发布时间】:2010-12-16 02:51:35
【问题描述】:

我保存了我的 Java 源文件,指定它的编码类型为 UTF-8(使用记事本,默认情况下记事本的编码类型是 ANSI),然后我尝试使用以下代码编译它:

javac -encoding "UTF-8" One.java

但它给出了错误消息“

One.java:1: illegal character: \65279

?public class One {

^
1 error

有没有其他方法,我可以编译这个?

这里是来源:

public class One {
    public static void main( String[] args ){
        System.out.println("HI");
    }
} 

【问题讨论】:

    标签: java unicode compiler-errors javac


    【解决方案1】:

    您的文件 被读取为 UTF-8,否则永远不会出现值为“65279”的字符。根据the javac documentationjavac 期望您的源代码采用平台默认编码:

    如果未指定-encoding,则使用平台默认转换器。

    十进制 65279 是十六进制 FEFF,即Unicode Byte Order Mark (BOM)。这在 UTF-8 中是不必要的,因为 UTF-8 总是被编码为八位字节流并且没有字节序问题。

    记事本喜欢在 BOM 中粘贴,即使它们不是必需的,但有些程序不喜欢找到它们。正如其他人所指出的,记事本不是一个很好的文本编辑器。切换到其他文本编辑器几乎肯定会解决您的问题。

    【讨论】:

    • +1:这里是替代方案:使用 notepad++、editplus 或 consorts,或者,只有当您很好地掌握在命令行中编码/构建/运行 java 时,才可以使用 Eclipse 之类的 IDE
    • 记事本可以很好地判断文件是否 UTF-8(或UTF-16),但恕我直言,这个问题非常严重,很多人都被绊倒了由它。
    • 记事本在其中粘贴了一个 BOM,以便稍后(或任何其他理解 BOM)可以确定该文件很可能是 UTF-8。
    • 这拯救了我的一天!从现在开始,我的电脑里只有 Notepad++。
    • @JohanBoulé:你在说什么?答案甚至没有提到 Notepad++,它只在cmets中提到。当答案显示“记事本”时,它指的是 Windows 内置应用程序“记事本”,而不是 Notepad++。
    【解决方案2】:

    在 Notepad++ 中打开文件并选择编码 -> 转换为不带 BOM 的 UTF-8。

    【讨论】:

      【解决方案3】:

      这不是您的文本编辑器的问题,而是 javac 的问题! Unicode 规范说 BOM 在 UTF-8 中是可选的,它并没有说它是禁止的! 如果 BOM 可以在那里,那么 javac 必须处理它,但它没有。实际上,在 UTF-8 文件中使用 BOM 有助于区分 ANSI 编码文件和 Unicode 编码文件。

      删除 BOM 的建议解决方案只是一种解决方法,而不是正确的解决方案。

      这个错误报告表明这个“问题”永远不会被修复:https://web.archive.org/web/20160506002035/http://bugs.java.com/view_bug.do?bug_id=4508058

      由于此线程在“javac BOM”搜索的前 2 个 google 结果中,因此我将其留给未来的读者。

      【讨论】:

      • 由于JDK-6378911 影响预期读取 BOM 的代码,所有 UTF-8 流的一般 Java 更改已恢复。它需要在javac 本身中修复。
      【解决方案4】:

      试试javac -encoding UTF8 One.java

      没有引号,它是 UTF8,没有破折号。

      See this forum thread for more links

      【讨论】:

      • 问题是记事本添加的BOM和javac不需要的BOM
      【解决方案5】:

      见下文 例如我们可以用一个程序讨论(泰卢固语单词)

      程序 (UnicodeEx.java)

      class UnicodeEx {  
          public static void main(String[] args) {   
              double ఎత్తు = 10;  
              double వెడల్పు = 25;   
              double దీర్ఘ_చతురస్ర_వైశాల్యం;  
              System.out.println("The Value of Height = "+ఎత్తు+" and Width = "+వెడల్పు+"\n");  
              దీర్ఘ_చతురస్ర_వైశాల్యం = ఎత్తు * వెడల్పు;  
              System.out.println("Area of Rectangle = "+దీర్ఘ_చతురస్ర_వైశాల్యం);  
          }  
      }
      

      这是保存为“UnicodeEx.java”并将编码更改为“unicode”的程序

      **如何编译**

      javac -encoding "unicode" UnicodeEx.java

      如何执行

      java UnicodeEx

      Height = 10.0 和 Width = 25.0 的值

      矩形面积 = 250.0

      【讨论】:

      • 我在处理带有 UTF-8 BOM 的 UTF-8 编码源文件时遇到了问题。转换为 UTF-16 LE(带有相应的 BOM)并将 -encoding unicode 添加到编译好的 javac 命令行。
      【解决方案6】:

      我知道这是一个非常古老的线程,但我在使用 PHP 而不是 Java 时遇到了类似的问题,Google 把我带到了这里。我在 Notepad++(不是普通的记事本)上编写 PHP,并注意到每次调用包含文件时都会出现一条额外的白线。 Firebug 显示这些额外的行中有一个 65279 字符。

      实际上,主 PHP 文件和包含的文件都以 UTF-8 编码。但是,Notepad++ 也可以选择编码为“UTF-8 without BOM”。这解决了我的问题。

      底线:UTF-8 编码会在这里和那里插入这个额外的 BOM 字符,除非您指示编辑器在没有 BOM 的情况下使用 UTF8。

      【讨论】:

        【解决方案7】:

        在这里工作正常,甚至在记事本中编辑。故事的寓意是,不要使用记事本。记事本可能会在其中插入或愉快地向您隐藏其中的不可打印字符。

        【讨论】:

        • BOM(字节顺序标记)是不可打印的字符,这意味着它应该在编辑窗口中隐藏。然而,任何好的文本编辑器都应该意识到这个标记的存在并尊重它包含的任何信息。使用十六进制/二进制编辑器显示允许您检查 BOM 的构造方式。 BOM 只会导致错误编写或不符合 unicode 的工具出现问题,任何在 BOM 存在时出现故障的工具都应尽快修复(看在上帝的份上,这是 2015 年......!)。以下是有关 BOM 的更多信息:en.wikipedia.org/wiki/Byte_order_mark
        • 但我完全同意整个“不使用记事本”的想法:)
        【解决方案8】:

        我遇到了同样的问题。为了解决它,在十六进制编辑器中打开文件,在文件开头发现三个“不可见”字节。我删除了它们,编译成功了。

        【讨论】:

        【解决方案9】:
        • 使用写字板或除记事本以外的任何其他编辑器打开文件。

        • 选择另存为类型为文本文档 - MS-DOS 格式

        • 重新打开项目

        【讨论】:

        • 这是个糟糕的建议……文档中已经存在的 Unicode 字符会怎样?
        【解决方案10】:

        使用适用于 Linux 用户的解决方案扩展现有答案

        要一次删除所有 .java 文件上的 BOM,请转到您的源目录并执行

        find -iregex '.*\.java' -type f -print0 | xargs -0 dos2unix

        需要安装findxargsdos2unix,大多数发行版中都应该包含它们。第一条语句递归查找当前目录中的所有.java 文件,第二条语句使用dos2unix 工具对每个文件进行转换,该工具旨在转换行尾但也删除BOM。

        如果您正确配置版本控制,则行尾转换应该没有影响,因为它应该已经在 Linux 上采用 Linux \n 格式,但请注意它也会这样做,以防您遇到以下罕见情况之一:这不是故意的。

        【讨论】:

          【解决方案11】:

          在 Intellij Idea(Settings>Editor>File Encodings) 中,项目编码为“windows-1256”。所以我使用下面的代码将静态字符串转换为utf8

          protected String persianString(String persianStirng) throws UnsupportedEncodingException {
              return new String(persianStirng.getBytes("windows-1256"), "UTF-8");
          }
          

          现在好了! 根据文件编码,您应该将“windows-1256”更改为正确的

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-06-30
            • 2010-11-03
            相关资源
            最近更新 更多