如何正确使用StreamWriter类?

vet*_*ori 9 c# streamwriter

我正在使用StreamWriter类进行文件操作,这段代码中是否有任何我没有看到的问题?

比如我需要将它放入一个try catch finally区块吗?

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

File.SetAttributes(streamFolder, FileAttributes.Hidden);
sr.Close();
Run Code Online (Sandbox Code Playgroud)

Ser*_*kiy 30

您的代码有什么问题?如果在关闭流之前发生某些异常,则流将保持打开状态,并且不会释放系统资源:

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

因此,您需要确定该流将被关闭.这可以通过try...finally块来实现:

StreamWriter sr = new StreamWriter(streamFolder);

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

但StreamWriter实现了IDisposable接口,因此您可以让C#编译器通过将writer使用包装到using块中来自动执行:

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

此代码将编译为:

StreamWriter sr = new StreamWriter(streamFolder);

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

手动实现之间的唯一区别是null-check和Dispose调用方法而不是Close.但实际上当你打电话Close()Dispose()执行相同的代码时:

this.Dispose(true);
GC.SuppressFinalize(this);
Run Code Online (Sandbox Code Playgroud)

您可以阅读有关Dispose方法实现的更多信息.


Dan*_*zka 6

您应该使用using语句:

using (StreamWriter sr = new StreamWriter(streamFolder))
{
    sr.Write(details);
    File.SetAttributes(streamFolder, FileAttributes.Hidden);
}
Run Code Online (Sandbox Code Playgroud)

在using块的末尾,将调用StreamWriter.Dispose,无论是异常还是代码成功运行.


Joh*_*ers 5

你想用:

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

      File.SetAttributes(streamFolder, FileAttributes.Hidden); 
  }
Run Code Online (Sandbox Code Playgroud)

你不需要Close.


ole*_*sii 5

将它包裹在一个using块中

using(StreamWriter sr = new StreamWriter(streamFolder))
{
      sr.Write(details);
      File.SetAttributes(streamFolder, FileAttributes.Hidden);
}
Run Code Online (Sandbox Code Playgroud)

确保你的命名是好的,所以streamFolder应该是一个fName.如果您觉得可以处理一些IO(或其他)异常,也可以将此代码放入try-catch-finally:

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();
}
Run Code Online (Sandbox Code Playgroud)

  • @vettori你应该知道`using`被编译器翻译成`try-finally`.所以你仍然得到这个代码.做任何微优化都会谨慎. (2认同)