6

I was wondering if it necessary to call Close() in the following situation (if not necessary, why?)

using (var file = System.IO.File.OpenText(myFilePath))
{
...
}

I presume it is necessary in the following situation

StreamWriter file2 = new System.IO.StreamWriter(myFilePath);
newFileContents.ForEach(file2.WriteLine);
file2.Close();

Is it correct?

Edit:

I thought my question is close() - specific, might have been the difference between reading and writing....

Mooing Duck
  • 64,318
  • 19
  • 100
  • 158
Yulia V
  • 3,507
  • 10
  • 31
  • 64
  • So far I haven't seen an answer worthy of my upvote. – Robert Harvey Feb 27 '13 at 19:11
  • 2
    The second snippet is not correct, it will fail to close the file when the code throws an exception. Close() exists as a separate method mostly because the *using* statement isn't always appropriate. Sometimes you might want to keep the file open for a while, beyond a single method. – Hans Passant Feb 27 '13 at 19:14
  • @RobertHarvey: No answer is going to be given worthy of upvote because all the answers have been given before (incl. mine) :) http://stackoverflow.com/questions/278902/using-statement-vs-try-finally http://stackoverflow.com/questions/567138/when-should-i-use-using-blocks-in-c/568231 http://stackoverflow.com/questions/614959/using-the-using-statment-in-c-sharp – IAbstract Feb 27 '13 at 19:16

6 Answers6

12

With the using construct you get IDisposable.Dispose called automatically at the end of the code block which will close the file. If you don't use the using statement you have to call Close yourself.

With using you also automatically get built-in try/finally exception handling which will behave more gracefully if something goes wrong before you exit your using block. That's another reason using using is a good idea instead of rolling your own.

In your case the using construct is shorthand for:

StreamWriter file2 = new System.IO.StreamWriter(myFilePath);
try
{
   newFileContents.ForEach(file2.WriteLine);
}
finally
{
   if (file2!= null)
       ((IDisposable)file2).Dispose();
}

If you decompile StreamWriter's implementation of Dispose you will see this call (among others):

this.stream.Close();

in the finally block (If you need absolute proof ;-)

Paul Sasik
  • 79,492
  • 20
  • 149
  • 189
  • 1
    Finally, an answer I can upvote. Note that `IDisposable` interface is specified in the `TextWriter`, from which `StreamWriter` inherits – Robert Harvey Feb 27 '13 at 19:12
  • `using()` is shorthand for a try/finally but yes, the finally block calls `Dispose()` – H H Feb 27 '13 at 19:14
  • I would note that your explanation of *"The using construct is shorthand for:"* is wrong. Conceptually it's fine, but you forgot the `try/finally`, which is really the most important part. – Ed S. Feb 27 '13 at 19:15
2

OpenText returns a StreamReader, which inherits TextReader, which inherits the IDisposable interface, which specifies a Dispose() method.

When the using statement goes out of scope, it calls the Dispose() method on the StreamReader's implementation of Dispose(), which in turn closes the stream (i.e. the underlying file) The whole thing is wrapped in a try/finally block under the covers, which guarantees that Dispose() will always be called.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
0

the using structure calls the object's Dispose method when it reaches the end of the script block. This method closes the file.

Any time you work with a file, you need to make sure to call Dispose or Close in order to let Windows know that the file is free for editing.

Matthew Shea
  • 567
  • 5
  • 14
0

I was wondering if it necessary to call Close() in the following situation (if not necessary, why?)

No because the using statement disposes of the object - and thus removes unmanaged resources.

I presume it is necessary in the following situation

Yes, here it would be required so that the unmanaged resources were cleaned up.

Mike Perrenoud
  • 66,820
  • 29
  • 157
  • 232
0

Correct.

  1. If wrapped in using clause, a file.Close() is not required
  2. If not wrapped, you are responsible for Close() and Dispose()
IAbstract
  • 19,551
  • 15
  • 98
  • 146
0

It's not necessary because Dispose() will close the underlying file. However since that's an implementation detail it's good practice to explicitly call Close() when you're done with the stream.

D Stanley
  • 149,601
  • 11
  • 178
  • 240