我看了How can I detect the encoding/codepage of a text file 检测编码是不可能的。但是,是否可以检测编码是否是允许的两种中的一种?
例如,我允许用户使用Unicode UTF-8
和iso-8859-2
作为他们的csv文件。有可能检测它是前者还是后者?
答案 0 :(得分:2)
例如我允许用户使用 Unicode UTF-8和iso-8859-2为他们的 csv文件。有可能检测到 无论是前者还是后者?
100%精度是不可能的,因为,例如,字节C3 B1在ISO-8859-2中是“ñ”的同等有效表示,因为它们在UTF-8中是“ñ”。实际上,因为ISO-8859-2为所有256个可能的字节分配了一个字符,所以每个 UTF-8字符串也是一个有效的ISO-8859-2字符串(如果是非ASCII,则代表不同的字符)。
然而,反过来却不是这样。 UTF-8对什么序列有效有严格的规定。超过99%的可能的8个八位字节序列不是有效的UTF-8。你的CSV文件可能比这长得多。因此,如果您:
,您可以获得良好的准确性然而,有可能检测到 编码是否是两个中的一个 允许?
通过验证可以可靠地检测UTF-32(字节顺序),UTF-8和CESU-8。 UTF-16可以通过BOM的存在来检测(但不能通过验证来检测,因为偶数长度的字节序列是无效的UTF-16的唯一方法是使用不成对的代理)。
如果您至少有一个“可检测”编码,那么您可以检查可检测的编码,并使用不可检测的编码作为后备。
如果两种编码都是“不可检测的”,如ISO-8859-1和ISO-8859-2,那么它就更难了。您可以尝试使用chardet使用的统计方法。
答案 1 :(得分:0)
由于无法检测编码,即使将其限制为两种可能的编码,您仍然无法检测到它。
我唯一可以想到的是你可以尝试用两种可能的编码中的一种编码,但是你必须检查它是否正确。这将涉及解析文本,即使这样,如果它是正确的,你也不会100%确定。
答案 2 :(得分:0)
这两种编码对于所有八位字节都具有相同的含义< 128。
所以你需要查看八位字节> = 128来做出决定。由于在UTF-8八位字节中> = 128总是出现在组中(对于编码单个代码点的较长序列上的2个八位字节),则三个八位字节序列{< 128,> = 128,< 128}将是一个ISO-8859-2的指示。
如果文件在ASCII之外不包含或非常少的八位字节(即<128),那么您的确定能力将是不可能的或有限的。当然,如果文件以UTF-8编码的BOM开头(很可能是从Windows开始),那么你知道它是UTF-8。
使用一些依赖于启发式的元数据(因为XML与其声明一样)通常更可靠,因为有可能有人向您发送了ISO-8859-3。
答案 3 :(得分:0)
如果您使用StreamReader,则会出现过载,如果可能(BOM)会检测编码,但如果检测失败则默认为UTF8。
我建议您使用两个选项(UTF8或Current),如果用户选择当前使用
var encoding = Encoding.GetEncoding(
CultureInfo.CurrentCulture.TextInfo.OEMCodePage);
var reader = new StreamReader(encoding);
最有希望成为正确的编码。
答案 4 :(得分:0)
请参阅我(最近)对相关问题的回答:How can I detect the encoding/codepage of a text file
此课程将检查该文件是否为可能,该文件为UTF-8,然后它会尝试猜测它是否可能。