在StreamWriter和StreamReader上完成

时间:2016-04-28 10:26:44

标签: c#

如果我有这个:

StreamWriter cout = new StreamWriter("test.txt");
cout.WriteLine("XXX");

// here IOException...
StreamReader cin = new StreamReader("test.txt");
string text = cin.ReadLine();

clr抛出IOException,因为我还没有关闭cout

事实上,如果我这样做:

StreamWriter cout = new StreamWriter("test.txt");
cout.WriteLine("XXX");

cout.Close();

StreamReader cin = new StreamReader("test.txt");
string text = cin.ReadLine();

我也不例外。

但如果我这样做然后退出应用程序:

StreamReader cin = new StreamReader("test.txt");
string text = cin.ReadLine();

不关闭cin文件可以从OS打开和写入。

然而,阅读StreamReader.cs的源代码我没有'找到析构函数方法(即~StreamReader(...))。那么,如果垃圾收集器没有调用Dispose并且没有最终确定方法,谁会释放该文件?

4 个答案:

答案 0 :(得分:4)

在内部,StreamReader uses a FileStream

 Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize, FileOptions.SequentialScan, Path.GetFileName(path), false, false, checkHost);

FileStream类,是最终访问文件的类,因此需要保证清理does have a finalizer,它关闭实际的底层流。 Dispose上的StreamReader方法仅calls the Close on the underlying FileStream

答案 1 :(得分:3)

StreamReaderStreamWriter使用FileStream来访问该文件。 FileStream使用SafeFileHandle来存储底层操作系统文件句柄。由于SafeFileHandle类控制非托管资源,因此它正确地具有关闭文件句柄的终结器(您称之为析构函数)。

  

但如果我这样做然后退出应用程序:[...]没有关闭cin文件可以从操作系统打开和写入

当进程终止时,该进程使用的所有资源都将释放到操作系统。如果您的应用程序忘记关闭文件句柄并不重要(即使SafeFileHandle不会忘记")。无论您的应用程序写得多么糟糕,您都会始终观察所描述的行为。

我只想指出使用StreamReaderStreamWriter及类似类的最佳方式是using

using (StreamWriter cout = new StreamWriter("test.txt")) {
  cout.WriteLine("XXX");
}

using (StreamReader cin = new StreamReader("test.txt")) {
  string text = cin.ReadLine();
}

即使在处理文件时抛出异常,这也会在using块结束时确定性地关闭文件。

答案 2 :(得分:0)

操作系统有一个列表,其中进程(应用程序)具有打开的文件。如果您的进程在没有明确关闭文件的情况下终止,操作系统仍然知道它不再访问该文件,因此可以允许其他请求访问该文件。

答案 3 :(得分:0)

如果应用程序在关闭时没有被应用程序释放,那么操作系统会释放应用程序拥有的句柄和内存。无论如何,我确信Stream有终结器。