4

鉴于此示例代码:

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行上的内容?在我看来这是可能的,因为你的平均 CPU 工作速度比你的平均 HDD 快得多,但我今天一直在测试这个,到目前为止,当我在线读取文件时,第 3 行写入的字符串始终存在8. 我在想,在将所有数据写入文件/从文件中读取之前,该语句可能不会关闭流,从而防止了我所询问的那种情况。C:\file.txtStreamReader.ReadToEndusing

我一直在阅读MSDN 上的StreamWriter.Close方法,它说明了以下内容:

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

但它没有说明数据何时会被写入底层流。

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

4

4 回答 4

3

调用 Close 后,数据可能不会实际出现在 HDD 上,但系统(Windows 内核)会给出它的外观。最重要的是外观。

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

如果不是这种情况,就很难编写可靠的程序,因为效果的顺序可以在函数甚至进程之间任意改变。这将是混乱。所以系统保证了顺序一致性。

如果你想一想:如果这个序列化属性不存在,一个文件可能同时有多个内容!第一次阅读它,你会看到旧的内容。再读一遍,你突然发现变化出现了。幸运的是,这种行为是不可能的。

于 2012-11-10T23:17:34.843 回答
2

我在想,在将所有数据写入文件/从文件中读取之前,使用语句可能不会关闭流,从而防止了我所询问的那种情况。

是的,正是。using() 确保对象被完全释放。有关 using 语句的更多信息,请参阅http://msdn.microsoft.com/en-us/library/yh598w02(v=vs.80).aspx?ppud=4

也就是说,在关闭文件之前,它的数据将被清除。实际上,它会等待文件被写入。

于 2012-11-10T23:13:18.773 回答
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

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

于 2012-11-10T23:44:58.150 回答
-1

您应该改用Flush,它可以确保写入数据。

于 2012-11-10T23:12:40.710 回答