Maven 更改某些文件的编码
Maven change encoding to certain files
我的所有项目都采用 Cp1252 编码,但我用 UTF-8 编码的几个文件除外,它们包含特殊字符。
当我 运行 安装时,在这些文件中出现了一些错误:unclosed character literal
、illegal character: '\u00a8'
。使用编码为 UTF8 的插件进行安装时:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
错误不再显示在上述文件中,但在许多其他文件中,显示的错误是:unmappable character for encoding UTF-8.
我可以只为某些文件指定 UTF-8 编码吗?
另外,maven显示错误如下:
folder/file.java:[10,19] unclosed character literal
folder/file.java:[10,22] unclosed character literal
folder/file.java:[13,19] unclosed character literal
数字是什么意思?好像不是错误所在的行号。
[10,19]
表示:第10行第19个字符。
@VGR 准确解释了为什么以 CP1252 读取 UTF-8 编码的源文件会导致编译失败:任何 non-ASCII 字符在 UTF-8 中至少编码为 2 个字节。如果您随后错误地将这些字节读取为 Cp1252,您将获得 2 个或更多官方字符。考虑到 char 文字只允许内部有 1 个字符,代码现在有编译器错误。
没有办法告诉 maven 一些文件是 UTF-8 而一些文件是 Cp1252,除非你 运行 单独编译 运行s,这很难做到,会非常混乱和很难维护(所以,一个坏主意),并且根本无法工作,除非你涉及存根或者你是 'lucky' 并且两批中的一个是 'self contained' (绝对不包含对来自另一个 'batch').
的任何东西
所以让我们把它作为可行的选择去掉。剩下 2 个选项:
正确的选择 - 所有时间都是 UTF-8
将所有源文件视为 UTF-8。这比听起来容易;所有 ASCII 字符在 UTF-8 和 Cp1252 中的编码相同,因此只有 non-ASCII 个字符需要检查。这很容易找到:它实际上是 126 以上的所有字节。您可以使用许多工具来找到它们。 Here is an SO question with answers 关于如何在 linux 上执行此操作。
使用任何编辑器打开这些文件,清楚地表明它使用的是哪种编码(大多数开发人员编辑器都是正确的),重新加载编码直到这个字符看起来正确,然后 re-save 为 UTF-8,瞧.所有没有特殊字符的同时都是 UTF-8 和 Cp1252 - 你可以简单地使用 UTF-8 编码编译它们,它就可以正常工作。
现在您的所有代码都在 UTF_8 中。相应地配置您的 IDE 项目/只需将您的 maven pom 保留在 'it is UTF-8' 上,所有 maven-aware 项目工具将自动使用它。
更糟糕的选择 - backslash-u 转义
如果你不能那样做,因为一些工具读取那些源文件(不是 maven 和 javac,实际上几乎没有来自 java 生态系统的主要内容,因为 java 生态系统都非常了解 UTF-8)并且只是坚持将其解析为 Cp1252,对此您无能为力:有一种方法可以从源文件中删除所有 non-ASCII:backslash-u 转义。
概念 \u0123
在任何 java 文件中的任何地方都是合法的,而不仅仅是在字符串文字中。这意味着:具有该值的 unicode 字符(十六进制)。例如,这个:
class Test {
public static void main(String[] args) {
//This does nothing, right? \u000aSystem.out.println("Hello!");
}
}
当您 运行 它时, 实际上会打印 Hello!
。即使系统输出在评论中......还是?
\u000a
是换行符。所以,上面的文件被解析为一行注释,然后是换行符,所以 System.out 语句确实在那里,而不是在注释中。许多工具不知道这一点(例如 sublime text 和 co 将以注释绿色呈现该 sysout 语句),但 javac
并且,事实上,Java Lang Spec 是 crystal 明确的this: 上面的代码里面有一个真正的打印语句,没有被注释掉。
因此,您可以寻找所有 non-ASCII 并将其替换为 u 转义符,现在您的代码是混合的:无论您使用哪种编码,只要它是 ASCII 兼容编码,它的解析都是相同的, 并且几乎所有的编码都是(只有少数日文和其他东亚字符集,以及 UTF-16/UCS2/UCS4/UTF-32 风格的编码,是 non-ASCII 兼容的。Cp1252,Iso- 8859、UTF_8 本身、ASCII 本身、Cp850 和许多其他 'ASCII compatible',意思是,100% ASCII 文本由所有这些编码进行相同编码)。
要将事情变成u转义,在任何unicode网站上查找该符号的十六进制值并应用它。例如,é 变为 \u00E9
(参见 é) and ☃ becomes \u2603
(see unicode snowman)。
将这些转义符放在 where-ever 你在源文件中看到 non-ascii,即使你在字符串文字之外看到它:
合法java:
public class Fighter {
public void mêléeAttack() {}
}
但是.. 如果您混淆了编辑器中的编码设置和 maven 中的编码设置,那就太糟糕了。然而,这:
public class Fighter {
public void m\u00EAl\u00E9eeAttack() {}
}
意思是一样的,即使你弄乱了编码也能正常工作。它在您的编辑器中看起来真的很糟糕,这就是为什么这是一个相当糟糕的选择。
我的所有项目都采用 Cp1252 编码,但我用 UTF-8 编码的几个文件除外,它们包含特殊字符。
当我 运行 安装时,在这些文件中出现了一些错误:unclosed character literal
、illegal character: '\u00a8'
。使用编码为 UTF8 的插件进行安装时:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
错误不再显示在上述文件中,但在许多其他文件中,显示的错误是:unmappable character for encoding UTF-8.
我可以只为某些文件指定 UTF-8 编码吗?
另外,maven显示错误如下:
folder/file.java:[10,19] unclosed character literal
folder/file.java:[10,22] unclosed character literal
folder/file.java:[13,19] unclosed character literal
数字是什么意思?好像不是错误所在的行号。
[10,19]
表示:第10行第19个字符。
@VGR 准确解释了为什么以 CP1252 读取 UTF-8 编码的源文件会导致编译失败:任何 non-ASCII 字符在 UTF-8 中至少编码为 2 个字节。如果您随后错误地将这些字节读取为 Cp1252,您将获得 2 个或更多官方字符。考虑到 char 文字只允许内部有 1 个字符,代码现在有编译器错误。
没有办法告诉 maven 一些文件是 UTF-8 而一些文件是 Cp1252,除非你 运行 单独编译 运行s,这很难做到,会非常混乱和很难维护(所以,一个坏主意),并且根本无法工作,除非你涉及存根或者你是 'lucky' 并且两批中的一个是 'self contained' (绝对不包含对来自另一个 'batch').
的任何东西所以让我们把它作为可行的选择去掉。剩下 2 个选项:
正确的选择 - 所有时间都是 UTF-8
将所有源文件视为 UTF-8。这比听起来容易;所有 ASCII 字符在 UTF-8 和 Cp1252 中的编码相同,因此只有 non-ASCII 个字符需要检查。这很容易找到:它实际上是 126 以上的所有字节。您可以使用许多工具来找到它们。 Here is an SO question with answers 关于如何在 linux 上执行此操作。
使用任何编辑器打开这些文件,清楚地表明它使用的是哪种编码(大多数开发人员编辑器都是正确的),重新加载编码直到这个字符看起来正确,然后 re-save 为 UTF-8,瞧.所有没有特殊字符的同时都是 UTF-8 和 Cp1252 - 你可以简单地使用 UTF-8 编码编译它们,它就可以正常工作。
现在您的所有代码都在 UTF_8 中。相应地配置您的 IDE 项目/只需将您的 maven pom 保留在 'it is UTF-8' 上,所有 maven-aware 项目工具将自动使用它。
更糟糕的选择 - backslash-u 转义
如果你不能那样做,因为一些工具读取那些源文件(不是 maven 和 javac,实际上几乎没有来自 java 生态系统的主要内容,因为 java 生态系统都非常了解 UTF-8)并且只是坚持将其解析为 Cp1252,对此您无能为力:有一种方法可以从源文件中删除所有 non-ASCII:backslash-u 转义。
概念 \u0123
在任何 java 文件中的任何地方都是合法的,而不仅仅是在字符串文字中。这意味着:具有该值的 unicode 字符(十六进制)。例如,这个:
class Test {
public static void main(String[] args) {
//This does nothing, right? \u000aSystem.out.println("Hello!");
}
}
当您 运行 它时, 实际上会打印 Hello!
。即使系统输出在评论中......还是?
\u000a
是换行符。所以,上面的文件被解析为一行注释,然后是换行符,所以 System.out 语句确实在那里,而不是在注释中。许多工具不知道这一点(例如 sublime text 和 co 将以注释绿色呈现该 sysout 语句),但 javac
并且,事实上,Java Lang Spec 是 crystal 明确的this: 上面的代码里面有一个真正的打印语句,没有被注释掉。
因此,您可以寻找所有 non-ASCII 并将其替换为 u 转义符,现在您的代码是混合的:无论您使用哪种编码,只要它是 ASCII 兼容编码,它的解析都是相同的, 并且几乎所有的编码都是(只有少数日文和其他东亚字符集,以及 UTF-16/UCS2/UCS4/UTF-32 风格的编码,是 non-ASCII 兼容的。Cp1252,Iso- 8859、UTF_8 本身、ASCII 本身、Cp850 和许多其他 'ASCII compatible',意思是,100% ASCII 文本由所有这些编码进行相同编码)。
要将事情变成u转义,在任何unicode网站上查找该符号的十六进制值并应用它。例如,é 变为 \u00E9
(参见 é) and ☃ becomes \u2603
(see unicode snowman)。
将这些转义符放在 where-ever 你在源文件中看到 non-ascii,即使你在字符串文字之外看到它:
合法java:
public class Fighter {
public void mêléeAttack() {}
}
但是.. 如果您混淆了编辑器中的编码设置和 maven 中的编码设置,那就太糟糕了。然而,这:
public class Fighter {
public void m\u00EAl\u00E9eeAttack() {}
}
意思是一样的,即使你弄乱了编码也能正常工作。它在您的编辑器中看起来真的很糟糕,这就是为什么这是一个相当糟糕的选择。