C# 如何从UTF-8编码文件中删除无效字符?

C# 如何从UTF-8编码文件中删除无效字符?,c#,unicode,encoding,utf-8,character-encoding,C#,Unicode,Encoding,Utf 8,Character Encoding,说明: 我在编写web应用程序时遇到了一个边缘案例。我接受要上传的UTF-8文件,并且我已经进行了检查,以确认它是UTF-8编码的(或者至少是最好的检查,显然没有银弹,我知道对于这个特定问题,还有许多其他关于堆栈溢出的问题) 作为一个测试,我获取了一个ANSI编码的文件,并将其转换为UTF-8,方法是(在单独的测试中)在Notepad++中将其转换为UTF-8,以及使用Encoding.UTF.GetBytes(inputStream)在C中动态解码为UTF-8(即使它是ANSI) 出现问题的地

说明

我在编写web应用程序时遇到了一个边缘案例。我接受要上传的UTF-8文件,并且我已经进行了检查,以确认它是UTF-8编码的(或者至少是最好的检查,显然没有银弹,我知道对于这个特定问题,还有许多其他关于堆栈溢出的问题)

作为一个测试,我获取了一个ANSI编码的文件,并将其转换为UTF-8,方法是(在单独的测试中)在Notepad++中将其转换为UTF-8,以及使用
Encoding.UTF.GetBytes(inputStream)
在C中动态解码为UTF-8(即使它是ANSI)

出现问题的地方

稍后,我将文件的原始数据作为XML文件中的元素之一放置。这就是问题所在。似乎有一个字符已从ANSI文件中保留(我假定)在UTF-8中无效。当我尝试使用以下命令加载XML时

XDocument xmlSample=XDocument.Load(outputPath)

我得到这个例外

{“给定编码中的无效字符。第10行,位置14。”}

在Visual Studio中看起来像这样

就像在记事本++中这样

下面是复制和粘贴的字符

来自NPP:
来自Visual Studio字符串查看器:

问题


如何从UTF-8编码的文件中删除无效字符,或者至少以合理的方式发现它们以便拒绝该文件?

首先,就您的示例而言,“温度”一词表明违规字符实际上是“度”符号(°,Unicode 176),因此全文显示为“温度(°C)”。在这种情况下,字符在ANSI中编码为
\260
字节,在UTF-8中编码为两个字节
\302\260
<代码>\260
(在本例中前面有左括号)无效UTF-8

第二,如果您在一年多之后仍然感兴趣,您能否澄清一下如何使用
Encoding.UTF.GetBytes()
将文件解码为UTF-8?
GetBytes()
读取字符,而不是字节,并且C中的字符没有编码;读取文件并将其转换为字符时已应用编码。
UTF.GetBytes()
所做的是将字符编码(而不是解码)为UTF-8字节序列


为了检查传入的字节序列,可以使用
Encoding.UTF.GetChars()
将字节序列解码为字符。根据您使用的构造函数,您可以获得一个“已清理”的字符串(如果出现问题,则会丢失数据)或收到一个关于有问题的字节序列的
DecoderFallbackException
,因此您可以拒绝输入。

复制并粘贴字符到问题中,这可能会提供一些线索。XmlReader.Create(字符串,设置)可以添加设置参数以忽略字符检查。它并不总是起作用,但对你来说可能会起作用。温度符号在xml中不是非法的,只是Microsoft实现需要对这些字符进行特殊处理。您能显示原始字符吗<代码>�
FFFD
)是一个“用于替换在Unicode中值未知或不可表示的传入字符”,而
C2A1
)是一个。我假设VisualStudio正在正确地用替换字符替换,而npp正在做一些奇怪的事情。注意:您可以通过
BitConverter.ToString(Encoding.UTF8.GetBytes(“�"))
在记事本++中,是否使用“编码为”或“转换为”来重新编码?编码为仅显示使用新选择的编码从磁盘读取的字节。由于ANSI和UTF-8在字符127以上不同,因此可能会产生意外的结果。编码菜单中的“转换为”条目实际上包含字符and正确地将它们转换为新选择的编码。您目前如何检查UTF-8的有效性?似乎这个测试不够彻底。