Shutdown on StreamWriter and StreamReader

If I have this:

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

clr throws an IOException because I do not close cout .

In fact, if I do this:

 StreamWriter cout = new StreamWriter("test.txt"); cout.WriteLine("XXX"); cout.Close(); StreamReader cin = new StreamReader("test.txt"); string text = cin.ReadLine(); 

I have no exception.

But if I do this, and then exit the application:

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

without closing the cin file can be opened and written to the OS.

However, after reading the source code of StreamReader.cs , I did not find the destructor method (i.e. ~StreamReader(...) ). So, who frees this file if the garbage collector does not call Dispose and there is no finalization method?

+6
source share
4 answers

StreamReader and StreamWriter use FileStream to access the file. FileStream uses SafeFileHandle to store the main file descriptor of the OS. Since the SafeFileHandle class manages an unmanaged resource, it correctly has a finalizer (what you call a destructor) that closes the file descriptor.

But if I do this and then exit the application: [...] without closing cin, the file can open from the OS and write

When the process ends, all resources used by this process will be released to the operating system. It doesn't matter, your application forgot to close the file descriptor (even if SafeFileHandle doesn't forget). You will always observe the described behavior no matter how poorly written your application.

I just want to point out that the best way to work with StreamReader and StreamWriter and similar classes is using :

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

This deterministically closes files when the using block ends, even if an exception is thrown while processing the file.

+3
source

Inside StreamReader uses a FileStream :

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

The FileStream class, which is the class that ultimately accesses the file and therefore needs to guarantee cleanup, has a finalizer that closes the actual underlying thread. The Dispose method on StreamReader simply calls Close on the underlying FileStream .

+4
source

The operating system has a list in which the process (application) has an open file. If your process terminates without explicitly closing the file, the operating system still knows that it no longer accesses the file and therefore may allow other requests to access the file.

0
source

The sytem operation frees descriptors and memory belonging to the application if they were not freed by the application, if it is closed. Anyway, I'm sure Stream has a finalizer.

0
source

All Articles