StreamWriter不能正确保存Unicode文件

3

我正在打开一个文本文件并删除第一行,以便使用批量插入将其导入数据库。以下是我的代码:

string tempFile = Path.GetTempFileName();
using (var sr = new StreamReader("F:\\Upload\\File.txt", System.Text.Encoding.UTF8))
{
    using (var sw = new StreamWriter(tempFile,true, System.Text.Encoding.UTF8))
    {
        string line;
        while ((line = sr.ReadLine()) != null)
        {
            if (line.Substring(0, 8) != "Nr. Crt.")
                sw.WriteLine(line);
        }
    }
}

System.IO.File.Delete("F:\\Upload\\File.txt");
System.IO.File.Move(tempFile, "F:\\Upload\\File.txt");

如果我打开生成的文件,Unicode字符会被替换成其他字符。例如,包含非断空格(Unicode U+00A0)的字符串:Value (注意Unicode字符)会变成Value�
如何避免这种情况?
编辑:
Notepad++已设置为“以UTF-8编码” 以下是它的外观图片:

你是在什么软件中打开文件的?你确定不是软件在读取它吗? - Rudi Visser
@rudi_visser 这不是显示错误,我已经尝试过记事本、Notepad++,并且在插入数据库时也是相同的错误值。 - Iulian
而且Notepad++正在以UTF8模式读取吗?抱歉,只是想确保,因为我最近使用几乎完全相同的方法将Unicode字符写入文件,并且它可以正常工作。 - Rudi Visser
Lulian记事本、Notepad++等仍需要知道格式是什么...你尝试过包含BOM吗? - Marc Gravell
是的,Notepad++并不是神仙,这正是我根据Marc在下面的回答所期望的。 - Jon Hanna
你有多确定 Upload\\File.txt 是 UTF8 编码的? - H H
2个回答

7

被转换为Value�

这三个奇怪字符的字节值为0xef 0xbd 0xbf。 这是代码点\ufffd的utf8编码,即替换字符�。 当读取utf编码文本并且该文本包含无效的编码字节序列时,将使用此字符。

直接指向File.txt的问题,它可能没有以utf-8编码。 如果您不知道该文件使用的编码方式,则第一个猜测是将Encoding.Default传递给StreamReader构造函数。


看起来我的文件没有以UTF-8编码。我从另一个应用程序接收此文件,它应该是UTF-8。这是为什么您永远不应该信任用户输入的另一个例子。将编码设置为默认值解决了我的问题。谢谢。 - Iulian

4

在我看来,它的编写很好,但是你正在使用的工具不支持UTF-8。在许多情况下,您需要明确告诉工具要期望什么编码方式。然而,一种常见的方法是添加BOM(“字节顺序标记”)。这很简单 - 只需使用new UTF8Encoding(true)作为编码方式,它会自动发生。在不期望BOM的工具中,这将显示为几个损坏的字符在开头 - 但大多数现代工具都知道它的含义,并会自动切换到UTF-8。重点是:UTF-8,UTF-16 LE和UTF-16 BE等的BOM略有不同,但是可以识别。更完整的列表在维基百科上。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接