C# 如何为正在读取的文件设置BOM表

C# 如何为正在读取的文件设置BOM表,c#,encoding,utf-8,C#,Encoding,Utf 8,我在阅读一个混合了阿拉伯语和西方文本的文件时遇到了问题。我将文件读入文本框,如下所示: tbx1.Text = File.ReadAllText(fileName.Text, Encoding.UTF8); FileStream fs = new FileStream(fileName.Text, FileMode.Open); StreamReader sr = new StreamReader(fs, Encoding.UTF8, false); tbx1.Text = sr.ReadTo

我在阅读一个混合了阿拉伯语和西方文本的文件时遇到了问题。我将文件读入文本框,如下所示:

tbx1.Text = File.ReadAllText(fileName.Text, Encoding.UTF8);
FileStream fs = new FileStream(fileName.Text, FileMode.Open);
StreamReader sr = new StreamReader(fs, Encoding.UTF8, false);
tbx1.Text = sr.ReadToEnd();
sr.Close();
fs.Close();
无论我尝试用什么值来代替Encoding.UTF8,我都会用乱码字符来代替阿拉伯语。西文文本显示得很好

我认为这可能是文本框定义方式的问题,但在启动时,我在文本框中写入了一些混合的西文/阿拉伯文文本,这显示得很好:

tbx1.Text = "Start السلا عليكم" + Environment.NewLine + "Here";
然后我打开记事本,将上面的文本复制到其中,然后保存文件,此时记事本保存对话框询问使用哪种编码

然后我将保存的文件呈现给我的代码,它正确地显示了所有内容

我检查了文件,发现在记事本的开头有3个二进制字节不可见:

我后来通过研究发现,3个字节代表BOM,这使C文件.ReadAllTextfileName.Text,Encoding.UTF8成为可能;根据需要读取/显示数据

让我困惑的是指定编码。UTF8值应该注意这一点

我能想到的唯一方法是编写一个步骤,将这些数据添加到文件的副本中,然后处理该文件。但这似乎有些冗长。只是想知道是否有更好的方法,或者为什么Encoding.UTF8不能产生期望的结果

编辑:

尽管尝试了答案中的建议,仍然没有运气

我将测试数据简化为只包含阿拉伯语,如下所示:

tbx1.Text = File.ReadAllText(fileName.Text, Encoding.UTF8);
FileStream fs = new FileStream(fileName.Text, FileMode.Open);
StreamReader sr = new StreamReader(fs, Encoding.UTF8, false);
tbx1.Text = sr.ReadToEnd();
sr.Close();
fs.Close();
代码如下:

tbx1.Text = File.ReadAllText(fileName.Text, Encoding.UTF8);
FileStream fs = new FileStream(fileName.Text, FileMode.Open);
StreamReader sr = new StreamReader(fs, Encoding.UTF8, false);
tbx1.Text = sr.ReadToEnd();
sr.Close();
fs.Close();
在第二行中尝试使用true和false,但两者给出相同的结果

如果我用记事本++打开文件,并指定阿拉伯语ISO-8859-6字符集,它将显示良好

以下是Notepad++中的外观,以及我将在文本框中显示的内容:

不确定问题是来自文件读取还是写入文本框

我将尝试检查读取后的数据以查看。但目前,我感到困惑。

StreamReader类有一个可以为您进行BOM测试的类:

using (var stream = new FileStream(fileName.Text, FileAccess.Read))
{
    using (var sr = new StreamReader(stream, Encoding.UTF8, true))
    {
        var text = sr.ReadToEnd();
    }
}
最后一个true参数是detectEncodingFromByteOrderMark:

detectEncodingFromByteOrderMarks参数通过查看流的前三个字节来检测编码。它自动识别:

UTF-8 小端码 和大端Unicode文本 如果文件 以适当的字节顺序标记开始。否则 使用用户提供的编码。见方法 了解更多信息


你可能在记事本写下文件后显示了它,这没有帮助。BOM是有争议的,Unix操作系统采用了utf-8,但大多数实用程序无法正确处理BOM。当您传递Encoding.UTF8时,您仍然将其留给File类来检测BOM表,并覆盖您的选择(如果有)。用实际文件内容更新十六进制转储文件。您确定应该是阿拉伯字符的字节实际上是所述字符的正确UTF8表示形式吗?我经常看到被冒充为UTF8的字符,但实际上是来自不同字符集(如ISO-8859-6或Windows-1256)的字节。这将导致类似这样的显示问题。谢谢Dean。我会看一下,看看文件中是否有非UTF8的内容。谢谢Dean。你的回答很有道理,但我还是没能得到想要的结果。在尝试您的建议后,请查看我对问题的编辑以查看结果。