10

I am using StreamWriter class for file operations, are there any problems in this code that I am not seeing?

Such as do I need to put it into a try catch finally block?

StreamWriter sr = new StreamWriter(streamFolder);
sr.Write(details);

File.SetAttributes(streamFolder, FileAttributes.Hidden);
sr.Close();
ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
vettori
  • 731
  • 8
  • 17
  • 26

5 Answers5

38

Whats wrong with your code? If some exception will occur before you close stream, then stream will stay open, and system resources will not be released:

StreamWriter sr = new StreamWriter(streamFolder);
sr.Write(details);
// some exception occurs here 
File.SetAttributes(streamFolder, FileAttributes.Hidden);
sr.Close();

So, you need to be sure, that stream will be closed. This could be achieved by try...finally block:

StreamWriter sr = new StreamWriter(streamFolder);

try 
{
   sr.Write(details);
   // some exception occurs here 
   File.SetAttributes(streamFolder, FileAttributes.Hidden);
}
finally
{
   sr.Close();
}

But StreamWriter implements IDisposable interface, so you can let C# compiler do it automatically for you by wrapping writer usage into using block:

using(StreamWriter sr = new StreamWriter(streamFolder)) 
{
   sr.Write(details);
   // some exception occurs here 
   File.SetAttributes(streamFolder, FileAttributes.Hidden);
}

This code will be compiled as:

StreamWriter sr = new StreamWriter(streamFolder);

try 
{
   sr.Write(details);
   // some exception occurs here 
   File.SetAttributes(streamFolder, FileAttributes.Hidden);
}
finally
{
   if (sr != null)
      sr.Dispose();
}

The only difference between manual implementation is null-check and method Dispose is called instead of Close. But actually when you call Close() or Dispose() same code will be executed:

this.Dispose(true);
GC.SuppressFinalize(this);

You can read more on Dispose method implementation.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
7

You should probably use a using statement:

using (StreamWriter sr = new StreamWriter(streamFolder))
{
    sr.Write(details);
    File.SetAttributes(streamFolder, FileAttributes.Hidden);
}

At the end of the using block, the StreamWriter.Dispose will be called, whether there was an exception or the code ran successfully.

Daniel Sklenitzka
  • 2,116
  • 1
  • 17
  • 25
  • is there any perfomance impacts here? i mean comparing .close() and using , because both are garbage collector? – vettori Jul 13 '12 at 09:04
  • No, it's about the same as wrapping the whole code in a try ... finally and call Dispose in the finally block. – Daniel Sklenitzka Jul 13 '12 at 09:08
  • well there is the implication that it can throw an exception on creation(file access violation, whatever). so you still need the try catch anyways. using is fine for something but not a catch all for other stuff. – Lassi Kinnunen Aug 06 '16 at 14:44
5

You want to use:

  using (StreamWriter sr = new StreamWriter(streamFolder))
  {
      sr.Write(details); 

      File.SetAttributes(streamFolder, FileAttributes.Hidden); 
  }

You don't need the Close.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
  • is there any perfomance impacts here? i mean comparing .close() and using , because both are garbage collector – vettori Jul 13 '12 at 09:02
  • @vettori There's no performance impact; the `using` statement is about ensuring that the StreamWriter is properly closed even if an exception is thrown within the `using`. – anton.burger Jul 13 '12 at 09:07
  • By using "using" the object gets disposed automatically after the context – Team-JoKi Jul 13 '12 at 09:07
5

Wrap it in a using block

using(StreamWriter sr = new StreamWriter(streamFolder))
{
      sr.Write(details);
      File.SetAttributes(streamFolder, FileAttributes.Hidden);
}

Make sure your naming is good, so streamFolder should probably be an fName. You can also put this code into try-catch-finally, if you feel you can handle some IO (or other) exceptions:

StreamWriter sr;
try
{
    sr = new StreamWriter(streamFolder);
    sr.Write(details);
    File.SetAttributes(streamFolder, FileAttributes.Hidden);
}
catch(IOException ex)
{
    //handling IO
}
finally
{
    if (sr != null)
        sr.Dispose();
}
oleksii
  • 35,458
  • 16
  • 93
  • 163
-3

System.IO.StreamWriter is a System.IDisposable

You have to dispose it. And why do you close something you don't open ?

  • Yes it opens it, so it must close it. Don't close something you don't open, it's a bad habit. – user1485585 Jul 17 '12 at 08:10
  • What is "it"? Do you mean that the StreamWriter must close itself? – John Saunders Jul 17 '12 at 16:21
  • I'm sure that it call method "Close" during dispose.Yes if an object is capable of autoopen, it is capable of autoclose. – user1485585 Jul 18 '12 at 08:44
  • I know this is kind of old, but the StreamWriter won't close itself unless you're either wrapping it in a `using` statement, or calling StreamWriter.Close on it. I'm not sure what user1485585 is referring to by "autoclose". – Brian Snow Sep 01 '13 at 20:00