给出这个示例代码:
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以确保所有数据都正确写入基础流。
但它没有说明何时将数据写入基础流。
提前感谢您对此主题的任何信息。我确实搜索了这个问题的答案,但我没有找到任何东西......我真的不知道要搜索的条件。
答案 0 :(得分:3)
调用Close后,数据可能不会物理存在于HDD上,但系统(windows Kernel)会给出它的外观。重要的是外观。
如果您从刚才写的文件中读取,Windows将询问硬盘或从缓存中提供服务。
如果情况并非如此,那么编写可靠的程序将会很困难,因为效果的顺序可能会在函数甚至进程之间任意改变。这将是混乱。因此系统保证了顺序的一致性。
如果您考虑一下:如果此序列化属性不存在,则文件可能同时包含多个内容!第一次阅读它,你会看到旧的内容。再次阅读,您会突然看到更改。幸运的是,这种行为是不可能的。
答案 1 :(得分:2)
是的,确切地说。 using()确保对象完全处理。有关using语句的详细信息,请参阅http://msdn.microsoft.com/en-us/library/yh598w02(v=vs.80).aspx?ppud=4。我在想,也许using语句不会关闭流 直到所有数据都写入/读取文件为止 防止我所询问的那种情况。
也就是说,在文件关闭之前,它的数据将被刷新。它确实会等待写入文件。
答案 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代替它,确保写入数据。