使用哪种编码来查找使用默认编码的代码?

时间:2011-12-22 09:32:19

标签: java character-encoding

编写从Java中读取文本的代码时常见的错误是忘记指定编码。如果您没有指定任何内容,Java将使用平台默认编码,最终会导致问题(“但它可以在我的计算机上运行!”)。

为了找到这些问题,我想使用一个不常见的默认编码,它应该尽可能多地打破I / O操作。这个想法是至少在ASCII之外的任何字符都会受到损坏。

我们的大多数文档都使用UTF-8编码。 ISO-8859-1可能有效,因为它只是保留输入(它是字节和字符之间的1:1映射)。任何变音符号都将读取两个/树字节序列。但我想知道我们是否可以做得更好。

您建议在list of supported encodings使用哪种编码?

3 个答案:

答案 0 :(得分:2)

UTF-16的默认编码很有可能“破坏”任何非UTF-16的文档。

但我认为你这样做是错误的。检测依赖于默认编码的狡猾代码的更好方法是为PMD之类的内容编写一些自定义规则。只需查看在String上使用有问题的方法和构造函数的代码,IO类等等。

(“使用奇怪的默认编码”方法的问题是,您的测试可能不足以执行所有违规代码,或者它可能会运行代码但不会检测到错误。)

答案 1 :(得分:1)

我认为16位或32位UTF中的任何一位都会给你很多“空”字符,这些字符应该会破坏很多字符串。使用BOM(字节顺序标记)也应该进一步“破坏”文件。

但我猜有些代码分析工具可以检查是否创建了没有编码的字符串,读者和编写器。

编辑: FindBugs似乎能够做到这一点:Dm: Reliance on default encoding (DM_DEFAULT_ENCODING)

答案 2 :(得分:1)

java.nio.charset.Charset方法newDecoder()返回Decoder。 Deconder的方法isAutoDetecting()isChasetDetected()detectedCharset()似乎对您的任务有用。不幸的是所有这些方法都是可选

我认为您应该使用所有可用的字符集(Charset.availableCharsets())并首先检查它们是否可自动检测。因此,当您获得新流时,首先尝试使用内置的自动检测机制来实现这些可选操作的字符集。

如果这些解码器中没有一个可以检测到chaset,你应该尝试解码流(如你所解释的)尝试应用其他字符集。要优化流程,请尝试使用以下条件对字符集进行排序。

首先是国家字母表。例如,在处理拉丁字母的那些之前尝试西里尔字符集。

在国家字母表中,选择一个具有更多字符的字母表。例如,日语和中文将在队列的开头。

这种策略的原因是你希望尽可能快地失败。如果您的文字不包含日文字符,则必须检查流中的第一个字符,以了解它是不是日文。但是,如果您尝试使用ASCII字符集来解码法语文本,则在看到第一个è之前,您可能需要阅读很多字符。