我正在开发一个c#项目,其中一些数据包含编码无法识别的字符。 它们显示如下:
“有些文字 中有特殊的 符号”。
我无法控制编码过程,数据也来自各种来源和各种格式的文件。 我希望能够标记包含错误或不完整字符的数据。现在我能够以这种方式检测它们:
if(myString.Contains("�"))
{
//Do stuff
}
虽然它确实有效,但在Contains函数中直接使用奇怪的符号并不合适。是不是有更清洁的方法来做到这一点?
编辑:
与负责阅读文件的团队核实后,他们就是这样做的:
var sr = new StreamReader(filePath, true);
var content = sr.ReadToEnd();
传递true
作为StreamReader的第二个参数应该从文件的BOM中检测编码,并使用它来读取内容。它并不总是有效,因为有些文件不承载这些信息,因此他们的数据读取错误的原因。
我们已经进行了一些测试,而使用StreamReader(filePath, Encoding.Default)
似乎适用于我们遇到问题的大多数文件。预计,之前工作的文件不再有效,因为它们不使用默认编码。
因此,对我们来说最好的解决方案是执行以下操作:读取尝试检测其编码的文件,然后如果不成功则使用默认编码再次读取它。
问题仍然存在:在尝试检测文件的编码后,如果数据读取不正确,我们如何检查?
答案 0 :(得分:6)
字符不是特殊符号。这是Unicode替换字符。这意味着代码尝试使用错误的代码页转换ASCII文本。代码页中没有匹配的任何字符都替换为 。
解决方案是使用正确的编码读取文件。 File
方法或StreamReader
使用的默认编码是UTF8。您可以使用适当的构造函数传递不同的编码,例如StreamReader(Stream, Encoding, Boolean)
。要使用系统区域设置的代码页,您需要使用Encoding.Default:
var sr = new StreamReader(filePath,Encoding.Default);
您可以使用StreamReader(Stream, Encoding, Boolean)构造函数从BOM中自动检测Unicode编码并回退到不同的编码。
假设文件是某种类型的Unicode或与您的系统区域设置匹配,您可以使用:
var sr = new StreamReader(filePath,Encoding.Default, true);
来自StreamReader的source表明DetectEncoding方法将检查文件的第一个字节以确定编码。如果找到一个,则使用它而不是提供的编码。该操作不会导致额外的IO,因为该方法会检查类的内部缓冲区
答案 1 :(得分:0)
我刚刚意识到您无法将原始文件加载到.NET字符串中,并且仍能够获得有关原始文件的完整信息。
project here使用Mlang api,它在猜测之前不会将文件加载到.NET字符串中做得更好。还有related SO question