C#:有没有办法发现文件的字符集编码使用了什么?

时间:2009-08-28 13:45:58

标签: c# character-encoding

有没有办法发现编码文件的字符集是什么?

7 个答案:

答案 0 :(得分:4)

可靠地执行此操作的唯一方法是在文本文件的开头查找byte order marks。 (该blob更一般地表示所使用的字符编码的字节序,但也表示编码 - 例如UTF8,UTF16,UTF32)。不幸的是,这种方法仅适用于基于Unicode的编码,在此之前没有任何内容(必须使用更不可靠的方法)。

StreamReader类型支持检测这些标记以确定编码 - 您只需将标志传递给参数:

new System.IO.StreamReader("path", true)

然后,您可以检查stremReader.CurrentEncoding的值以确定文件使用的编码。但请注意,如果不存在字节编码标记,则CurrentEncoding将默认为Encoding.Default

答案 1 :(得分:3)

请参阅:Detecting File Encodings in .NET

来自Msdn

  

没有很好的方法来检测任意ANSI代码页,尽管有一些尝试是基于文本中间某些字节序列的概率来做到这一点。我们不在StreamReader中尝试。一些文件格式(如XML或HTML)可以在文件的第一行指定字符集,因此Web浏览器,数据库和类(如XmlTextReader)可以正确读取这些文件。但是许多文本文件没有内置这种类型的信息。

答案 2 :(得分:0)

100%可靠性无法做到这一点。您必须决定您习惯的成本与准确性权衡。我在本回复中讨论了许多可能的算法(包括优点和缺点):PowerShell search script that ignores binary files

答案 3 :(得分:0)

答案 4 :(得分:0)

我在C ++中编写了一段时间,它变得相当复杂。这就是我所做的(接受匹配的第一个):

  • 寻找Byte Order Marks
  • 检查文本是否有效UTF-32 BE / LE
  • 检查文本是否有效UTF-16 BE / LE
  • 检查文本是否有效UTF-8
  • 假设当前代码页

这可以解决许多无BOM的文本文件,但对使用自定义ANSI代码页存储的文本没有帮助。

对于这些,没有可能的确定性检测。例如。使用“东欧”编码保存的文件并加载到具有“西欧”默认代码页的计算机上将会出现乱码。

在这种情况下唯一可能的帮助是让用户选择代码页(根据用户体验,最好的方法是让用户在看到文本时更改假定的编码)。

它在测试集上运行正常,但当然可能存在误解,如果不可能的话。

代码页可以通过对文本的统计分析来确定(例如,包含非ASCII字符的字符对和三元组的频率,或不同语言的单词列表,但我没有找到任何合适的方法来尝试。

Win32 IsTextUnicode非常糟糕,只检查UTF-16,可能是记事本中“丛林隐藏事实”背后的罪魁祸首。

答案 5 :(得分:0)

正如peterchen所写,你应该在Notepad.exe中写下“bush hide the facts”,保存并重新打开它,看看有多难以检测到编码。

http://en.wikipedia.org/wiki/Bush_hid_the_facts

答案 6 :(得分:0)

要添加到可能有用的链接列表中,这是一个非常小的类,我把它放在一起检测unicode编码(有或没有BOM)与默认代码页(通常是Windows-1252,标记为" ASCII& #34;在.Net中作为Encodings.ASCII):

http://www.architectshack.com/TextFileEncodingDetector.ashx

它比StreamReader默认功能更进一步,基本上正是@peterchen在上面的回答中所描述的,除了这个C#代码:

  • 首先检查BOM,如果提供,则使用它
  • 否则,请检查文件可以编码的Unicode编码。
  • 对于找到的每个可能的unicode编码,检查所提供的数据的编码是否相似(假设主要是西欧内容)
  • 如果"可能" unicode编码看起来不太可能,使用提供的默认代码页/编码

很抱歉这个答案太晚了 - 我最近才清理课程并将其上线。