在StreamWriter和StreamReader上完成

xde*_*000 6 c#

如果我有这个:

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

// here IOException...
StreamReader cin = new StreamReader("test.txt");
string text = cin.ReadLine();
Run Code Online (Sandbox Code Playgroud)

clr扔了一个IOException因为我没有关闭cout.

事实上,如果我这样做:

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

cout.Close();

StreamReader cin = new StreamReader("test.txt");
string text = cin.ReadLine();
Run Code Online (Sandbox Code Playgroud)

我也不例外.

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

StreamReader cin = new StreamReader("test.txt");
string text = cin.ReadLine();
Run Code Online (Sandbox Code Playgroud)

无需关闭cin文件即可从OS打开和写入.

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

Jam*_*rpe 5

在内部,StreamReader 使用FileStream

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

该类FileStream是最终访问文件并因此需要保证清理的类,它确实有一个终结器,它关闭实际的底层流。Dispose上的方法只是StreamReader调用底层CloseFileStream


Mar*_*age 3

StreamReaderStreamWriter使用 aFileStream来访问该文件。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();
}
Run Code Online (Sandbox Code Playgroud)

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