有没有人知道为什么native2ascii会生成小写的十六进制代码,而Properties.store()会生成大写的十六进制代码?
示例:
保存在使用\u4FDD\u5B58
时编码为Properties.store()
,但在使用\u4fdd\u5b58
时编码为native2ascii
有没有办法控制这个?
答案 0 :(得分:3)
我不知道为什么,但我知道这无所谓(无论如何,对Java来说,它可能对你很重要)。允许Unicode转义具有较高的或小写十六进制数字,因此对Java来说无关紧要(即使是混合大小写有效)。
他们不同的原因可能就像他们由两个不同的人写的一样简单。
有没有办法控制它?从我能看到的不容易。 native2ascii
似乎没有任何控制输出的选项(它允许选项来控制JVM但不允许控制该级别)。
Properties.store()
使用OutputStream
(并且Properties.load()
使用InputStream
),您可能可以将其子类化以过滤Unicode转义,但这似乎是一项非常多的工作(什么看起来可疑的好处。
也许如果你能告诉我们为什么你需要这个,可能还有另一种方式。
更新1:
你可以做的一件事是通过过滤器传递native2ascii
输出,该过滤器将Unicode转义序列转换为大写。以下代码ucunicode.c
应该能够做到这一点,尽管我只是粗略测试。只需执行:
native2ascii inputFile | ucunicode
您应该会看到\u00EF\u00BB\u00BF
而非\u00ef\u00bb\u00bf
的内容。
#include <stdio.h>
int main (void) {
int count = 0; // used for converting four hex digits after "\u".
int chminus2 = -1; // character from two passes ago.
int chminus1 = -1; // character from one pass ago.
int ch; // character for this pass.
// Standard filter loop.
while ((ch = getc (stdin)) != EOF) {
if (count-- > 0) {
// If processing Unicode escape sequence, uppercase letters.
putchar (((ch >= 'a') && (ch <= 'f')) ? ch - 'a' + 'A' : ch);
} else {
// Normal processing, detect escape sequence and flag it.
if ((chminus2 != '\\') && (chminus1 == '\\') && (ch == 'u')) {
count = 4;
}
// In any case, output the character.
putchar (ch);
}
// Shift characters "left".
chminus2 = chminus1;
chminus1 = ch;
}
return 0;
}
可能存在边缘情况,这不能很好地处理。我很确定它会处理所有有效输入,但可能会在\u1\\u0000
之类的无效输入中断,但是,因为这意味着你的native2ascii
被破坏了,你需要自己调试它们。不过这是一个好的开始。
更新2:
或者,作为最后一个解决方案,OpenJDK项目在native2ascii
中有jdk\src\share\classes\sun\tools\native2ascii\
的实际source files(以及其他所有不受版权保护的内容),你可以降低并编译自己(GPL2适用)。文件为Main.java
,A2NFilter.java
和N2AFilter.java
(以及一些资源文件)。您只需更改N2AFilter.java
即可致电:
String hex = Integer.toHexString(buf[i]).toUpperCase();
而不只是:
String hex = Integer.toHexString(buf[i]);
事实上,通过检查源代码,您可以看到Properties.store()
(在jdk/src/share/classes/java/util/Properties.java
中)使用以下函数来创建它的Unicode转义:
private static final char[] hexDigit = {
'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
};
private static char toHex (int nibble) {
return hexDigit[(nibble & 0xF)];
}
这解释了为什么它会产生大写,而native2ascii
产生小写。
答案 1 :(得分:1)
我只是碰到了这个,我有一个令人讨厌的原因:我只是将一个(unicode).properties文件转换为另一个(自制的XML)格式,并将导出函数转换回.properties。此函数使用Properties.store()
,而原始的Unicode .properties由ant通过native2ascii
转换。我现在想要比较它们产生类似的结果,因此在每个结果上应用sort
并在结果上应用diff
。事实上,大多数产生的不同线条都是由于这些情况在\ u-escape中存在差异。 (我想我会用一个快速的sed脚本来转换其中一个文件的情况。)
所以,这是我们的sed脚本:s/\\u([0-9A-F]{4})/\\u\L\1\E/g
(更改为小写)或s/\\u([0-9A-F]{4})/\\u\U\1\E/g
(更改为大写)。我不得不改变一点,因为Properties.store()
还从!
到\!
,=
到\=
,:
转义{ {1}}。