【发布时间】:2017-05-05 19:43:33
【问题描述】:
我们的 Maven 项目中 .java 文件的源编码,它存储在 Subversion 中,主要是 ASCII,一些文件是 UTF-8。
我认为目的是这些文件将是 UTF-8。在 pom 文件中,源编码指定为 UTF-8。
现在我们的构建失败了,特别是我们的 SonarQube 分析在 .java 文件上失败,该文件是 ISO-8859 并且有一个带有特殊字符的变量。认为使用特殊字符不是一个好主意,但除此之外,java 文件不应该具有一致的 (UTF-8) 编码吗?
或者大多数是 ASCII 而只有一些是 UTF-8 无关紧要?重要的是思想吗?
顺便说一句,我不明白这些文件是如何以 ASCII 编码结束的。当我使用像 SublimeText 这样的 IDE 或编辑器时,文件会以 UTF-8 结尾。
只有当我在 MS Windows 上使用记事本时才会得到 ASCII。 Java 开发人员通常不会将其用于编程。
我们是否应该将源文件更改为使用 UTF-8?或者也许这无关紧要,我们可以保持原样?
举个例子。使用 MS Windows,我使用 SublimeText 创建一个文件,使用 Notepad.exe 创建一个文件。我将文本 1234Ï 放在这些文件中。文本包含一个带两个点的特殊字符 I。
当我在 Linux 上使用file查看这些文件时
ostraaten@io:/tmp/iconv$ file sublimtext.txt
sublimtext.txt: UTF-8 Unicode (with BOM) text, with no line terminators
ostraaten@io:/tmp/iconv$ file notepad.txt
notepad.txt: ISO-8859 text, with no line terminators
ostraaten@io:/tmp/iconv$
因此,这表明记事本将文件保存为 ISO-8859,而不管内容如何。当我使用iconv检查文件时
ostraaten@io:/tmp/iconv$ iconv -f UTF-8 notepad.txt -o /dev/null
iconv: incomplete character or shift sequence at end of buffer
ostraaten@io:/tmp/iconv$ iconv -f UTF-8 sublimtext.txt -o /dev/null
ostraaten@io:/tmp/iconv$
我可以使用 SublimeText 打开并保存文件notepad.txt,编码仍然显示为 ISO-8859。
字符在两个文件中都正确显示。因此,这支持了编辑器尝试从文件内容中确定编码的想法。但在其他地方,该文件仍被标记并识别为 ISO-8859。
我可以使用iconv更改编码
ostraaten@io:/tmp/iconv$ iconv -f ISO-8859-15 -t UTF-8 notepad.txt > notepad-utf8.txt
ostraaten@io:/tmp/iconv$ file notepad-utf8.txt
notepad-utf8.txt: UTF-8 Unicode text, with no line terminators
ostraaten@io:/tmp/iconv$
straaten@io:/tmp/iconv$ iconv -f UTF-8 notepad-utf8.txt -o /dev/null
转换成功,因为消息不完整的字符消失了。
【问题讨论】:
-
UTF-8 与 ASCII 兼容。任何包含 ASCII 字符的文件也是有效的 UTF-8 文件。 (这就是 UTF-8 几乎适用于所有事物的原因之一)。此外,字符编码不是文件本身的属性。它是从文件的内容中检测到的。
-
当我用 SublimeText 创建一个包含一些普通字符的文件时,它确实显示为 UTF-8。在 MS Windows 上使用记事本创建的具有相同字符的文件显示为 ISO-8859。
-
那是因为编辑们只是在猜测编码是什么,他们选择了一种似乎与这些编码中的一种相匹配的编码。 “普通文本”同样可以有效地解释为 ASCII、UTF-8 或 ISO-8859-1。这取决于编辑者对合适编码的猜测,不同的编辑者可能有不同的规则从内容中猜测编码。