2012-03-30 89 views
1

半年前我面临烦人的问题。仍然无法修复它。 问题在于log4j日志记录,其中默认字符集是utf 8.如何检测Java中的字符集?

有时我收到不同编码的消息,CP1252。 (没有办法改变这一点)。 因此,登录utf8会使文本无法读取。 我可以以某种方式修复编码,并且这些文本在日志中是可读的。

但是,如果我将这个“编码修复”应用到正常的消息,它会被搞砸了。 我需要知道这种转换是否真的需要。不幸的是,我没有任何想法。

+4

不可能可靠地*检测*文本块的编码。你通常必须知道你在处理什么。据推测,您可以确定您在CP1252中接收消息的情况,不是吗?这里更大的场景是什么? – deceze 2012-03-30 01:31:41

+0

不是。我无法预测它:( 据我记得,正常的消息是utf 8和cp1251。 但是其中一些,可能依赖于windows语言,这就是它们为什么在CP1252中。 我可以让它们通过转换1252 - > 1251-> utf8。但它肯定会搞乱正常的。 – VirtualVoid 2012-03-30 01:44:35

回答

3

正如deceze所言,没有可靠的方法可以自动检测文本的编码。

大多数编码尝试使用1个字节作为结果,因为结果相同的字节序列表示在不同的编码中完全不同的字符串。你能够可靠地做的唯一的事情就是说“它不是有效的UTF8字符串”,其他常用的编码甚至没有严格的规则,哪些字节序列对它无效。

你最好的选择是知道消息的编码。下一个选项是将文本保存为“utf8 string”旁边的字节数组。

如果您的编码集非常有限(utf8/utf16/cp1252),您可以尝试使用一些启发法来检测 - 即UTF16中的大多数英文字符串将与其他字节一样为0,并且您可以尝试以UTF8查看字符串是否正确 - 如果不是 - 则可能是剩余的编码。

+0

似乎,检查utf 8字符串的有效性并不错。 这是正确的方法吗? – VirtualVoid 2012-03-30 01:49:20

+0

如果它已经是“字符串”时它到达你的代码可能太晚了,但如果它是字节数组转换为字符串使用Ut8编码也应该做检查(我不知道如何在Java中做它,只是假设它类似于C#)。检查出http://stackoverflow.com/questions/1677497/guessing-the-encoding-of-text-represented-as-byte-in-java其中包含详细的步骤和一些图书馆的参考。 – 2012-03-30 01:57:53

+0

这里是一种使用文件中的字节顺序标记来确定其编码的技术(如果在非cp1252编码文件中缺少BOM,则不保证工作)http://stackoverflow.com/questions/1835430/byte-order-mark -screws-UP-文件读入的Java。否则,请使用ICU4J – 2012-03-30 03:23:38

1

Apache Tika包含一个开源编码检测器。

也有商业替代品。

+0

我认为您必须非常绝望地将昂贵的(基于NLP的)编码检测器连接到消息应用程序的记录器。 – 2012-03-31 02:26:13