在StreamWriting之后立即将文件读取到同一文件

时间:2012-11-10 23:08:02

标签: c# streamreader race-condition streamwriter

给出这个示例代码:

1:   using (StreamWriter sw = new StreamWriter(@"C:\file.txt"))
2:   {
3:       sw.WriteLine(great_string);
4:   }
5:
6:   using (StreamReader sr = new StreamReader(@"C:\file.txt"))
7:   {
8:       sr.ReadToEnd();
9:   }

在第8行调用great_string时,第{3}行写的C:\file.txt是否可能不会出现在StreamReader.ReadToEnd中?在我看来,这是可能的,因为你的平均CPU工作速度比普通硬盘驱动器快得多,但我今天一直在测试,到目前为止,当我在线读取文件时,第3行写的字符串总是存在8.我在想,在将所有数据写入/读取文件之前,using语句可能不会关闭流,从而防止了我所询问的那种情况。

我一直在阅读MSDN上的StreamWriter.Close方法,并说明如下:

  

您必须调用Close以确保所有数据都正确写入基础流。

但它没有说明何时将数据写入基础流。

提前感谢您对此主题的任何信息。我确实搜索了这个问题的答案,但我没有找到任何东西......我真的不知道要搜索的条件。

4 个答案:

答案 0 :(得分:3)

调用Close后,数据可能不会物理存在于HDD上,但系统(windows Kernel)会给出它的外观。重要的是外观。

如果您从刚才写的文件中读取,Windows将询问硬盘或从缓存中提供服务。

如果情况并非如此,那么编写可靠的程序将会很困难,因为效果的顺序可能会在函数甚至进程之间任意改变。这将是混乱。因此系统保证了顺序的一致性。

如果您考虑一下:如果此序列化属性不存在,则文件可能同时包含多个内容!第一次阅读它,你会看到旧的内容。再次阅读,您会突然看到更改。幸运的是,这种行为是不可能的。

答案 1 :(得分:2)

  

我在想,也许using语句不会关闭流   直到所有数据都写入/读取文件为止   防止我所询问的那种情况。

是的,确切地说。 using()确保对象完全处理。有关using语句的详细信息,请参阅http://msdn.microsoft.com/en-us/library/yh598w02(v=vs.80).aspx?ppud=4

也就是说,在文件关闭之前,它的数据将被刷新。它确实会等待写入文件。

答案 2 :(得分:1)

alleywayjack的回答是正确的。观看时间:

    static void Main()
    {
        var file = @"c:\temp\test.bin";
        String huge = new String(new char[20 * 1024 * 1024]);
        var sw = new Stopwatch();
        var sw2 = new Stopwatch();
        sw.Start();
        using (var stream = new StreamWriter(file))
        {
            sw2.Start();
            stream.Write(huge);
            sw2.Stop();
        }
        sw.Stop();
        sw2.Stop();

        Console.WriteLine("Write 20MB to cache: " + (sw.Elapsed.TotalMilliseconds - sw2.Elapsed.TotalMilliseconds));
        Console.WriteLine("Write 20MB from cache to HD: " + sw2.Elapsed.TotalMilliseconds);
    }

输出:

Write 20MB to cache: 5   // ms (including preparing the stream) 
Write 20MB from cache to HD: 186   // ms

整个过程都是阻塞(同步)。

答案 3 :(得分:-1)

您应该使用Flush代替它,确保写入数据。