StreamWriter将BOM字符65279附加到文件末尾

时间:2014-12-04 16:32:56

标签: c# .net io stream streamreader

我在读取文件的同时打开了StreamWriter文件,这似乎导致了问题(这是一小段代码的较小片段,仅用于说明我的问题):

static void Main(string[] args)
{
    for (int i = 0; i < 3; i++)
    {
        using (FileStream stream = new FileStream("file.txt", FileMode.OpenOrCreate))
        using (StreamReader reader = new StreamReader(stream, Encoding.UTF8, false, 0x1000, true))
        using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8, 0x1000, true))
        {
            Console.WriteLine("Read \"" + reader.ReadToEnd() + "\" from the file.");
        }
    }
    Console.ReadLine();
}

上面的代码将输出:

Read "" from the file.
Read "" from the file.
Read "?" from the file.

如果文件已包含某些文本,则编写器会将BOM附加到最后,尽管从未调用过任何文本:

Read "TEXT" from the file.
Read "TEXT?" from the file.
Read "TEXT??" from the file.

为什么会出现这种行为?

2 个答案:

答案 0 :(得分:3)

正如我之前在关于字节顺序标记的评论中暗示的那样,您试图避免使用StreamWriter添加字节顺序标记。这基于您正在使用的编码器。

例如,尝试创建自己的编码器而不写入字节顺序标记:

static void Main(string[] args)
{
    for (int i = 0; i < 3; i++)
    {
        using (FileStream stream = new FileStream("file.txt", FileMode.OpenOrCreate))
        using (StreamReader reader = new StreamReader(stream, Encoding.UTF8, true, 0x1000, true))
        using (StreamWriter writer = new StreamWriter(stream, new UTF8Encoding(false), 0x1000, true))
        {
            Console.WriteLine("Read \"" + reader.ReadToEnd() + "\" from the file.");
        }
    }
    Console.ReadLine();
}

通过使用new UTF8Encoding(false)作为UTF8编码器,显式指示编码器不使用Unicode字节顺序标记。这在MSDN entry for the UTF8Encoding constructor

中有所描述

答案 1 :(得分:1)

好。我想即使你不写任何东西,作家也想写字节顺序标记。您将流位置移动到流的末尾,因此当您配置编写器时 - 它将字节顺序标记刷新到流的末尾。

试试此代码

    static void Main(string[] args)
    {
        for (int i = 0; i < 3; i++)
        {
            using (FileStream stream = new FileStream("sample.txt", FileMode.OpenOrCreate))
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8, false, 0x1000, true))
            using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8, 0x1000, true))
            {
                writer.Flush();
                Console.WriteLine("Read \"" + reader.ReadToEnd() + "\" from the file.");
            }
        }
        Console.ReadLine();
    }

你会看到预期的行为,没有&#39;?&#39;符号。