如何正确使用 StreamWriter 类?
Posted
技术标签:
【中文标题】如何正确使用 StreamWriter 类?【英文标题】:how to use StreamWriter class properly? 【发布时间】:2012-07-13 02:42:12 【问题描述】:我正在使用StreamWriter
类进行文件操作,这段代码中是否有我没有看到的问题?
比如我需要把它放到try catch finally
块中吗?
StreamWriter sr = new StreamWriter(streamFolder);
sr.Write(details);
File.SetAttributes(streamFolder, FileAttributes.Hidden);
sr.Close();
【问题讨论】:
【参考方案1】:您的代码有什么问题?如果在关闭流之前发生异常,则流将保持打开状态,并且不会释放系统资源:
StreamWriter sr = new StreamWriter(streamFolder);
sr.Write(details);
// some exception occurs here
File.SetAttributes(streamFolder, FileAttributes.Hidden);
sr.Close();
因此,您需要确定该流将被关闭。这可以通过try...finally
块来实现:
StreamWriter sr = new StreamWriter(streamFolder);
try
sr.Write(details);
// some exception occurs here
File.SetAttributes(streamFolder, FileAttributes.Hidden);
finally
sr.Close();
但是 StreamWriter 实现了IDisposable 接口,所以你可以让 C# 编译器自动为你做这件事,方法是将 writer 的使用情况包装到 using
块中:
using(StreamWriter sr = new StreamWriter(streamFolder))
sr.Write(details);
// some exception occurs here
File.SetAttributes(streamFolder, FileAttributes.Hidden);
这段代码将被编译为:
StreamWriter sr = new StreamWriter(streamFolder);
try
sr.Write(details);
// some exception occurs here
File.SetAttributes(streamFolder, FileAttributes.Hidden);
finally
if (sr != null)
sr.Dispose();
手动实现的唯一区别是空检查和方法Dispose
被调用而不是Close
。但实际上当你调用Close()
或Dispose()
时会执行相同的代码:
this.Dispose(true);
GC.SuppressFinalize(this);
您可以在Dispose method implementation 上阅读更多内容。
【讨论】:
【参考方案2】:您可能应该使用 using 语句:
using (StreamWriter sr = new StreamWriter(streamFolder))
sr.Write(details);
File.SetAttributes(streamFolder, FileAttributes.Hidden);
在 using 块结束时,StreamWriter.Dispose 将被调用,无论是出现异常还是代码运行成功。
【讨论】:
这里有性能影响吗?我的意思是比较 .close() 和 using ,因为两者都是垃圾收集器? 不,这与将整个代码包装在 try ... finally 中并在 finally 块中调用 Dispose 大致相同。 嗯,这意味着它可以在创建时抛出异常(文件访问冲突等)。所以无论如何你仍然需要try catch。 using 对某些东西很好,但对其他东西不是一概而论。【参考方案3】:你想使用:
using (StreamWriter sr = new StreamWriter(streamFolder))
sr.Write(details);
File.SetAttributes(streamFolder, FileAttributes.Hidden);
您不需要Close
。
【讨论】:
这里有性能影响吗?我的意思是比较 .close() 和 using ,因为两者都是垃圾收集器 @vettori 没有性能影响;using
语句是关于确保 StreamWriter 正确关闭,即使在 using
中抛出异常也是如此。
通过使用“使用”,对象会在上下文之后自动释放【参考方案4】:
将其包装在 using
块中
using(StreamWriter sr = new StreamWriter(streamFolder))
sr.Write(details);
File.SetAttributes(streamFolder, FileAttributes.Hidden);
确保您的命名正确,所以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();
【讨论】:
第二种方法会增加代码行数,我正在寻找优化的代码 @vettori 你应该知道using
被编译器翻译成try-finally
。所以你仍然得到这个代码。我会谨慎进行任何微优化。
@oleksii,是吗?在统一时,至少不会捕获文件异常。【参考方案5】:
System.IO.StreamWriter 是一个 System.IDisposable
你必须处理它。你为什么要关闭你不打开的东西?
【讨论】:
是的,它会打开它,所以它必须关闭它。不要关闭你没有打开的东西,这是一个坏习惯。 什么是“它”?您的意思是 StreamWriter 必须自行关闭吗? 我确定它在处理过程中调用了“关闭”方法。是的,如果一个对象能够自动打开,它就能够自动关闭。 我知道这有点老了,但 StreamWriter 不会自行关闭,除非您将其包装在using
语句中,或者在其上调用 StreamWriter.Close。我不确定 user1485585 所指的“自动关闭”是什么。以上是关于如何正确使用 StreamWriter 类?的主要内容,如果未能解决你的问题,请参考以下文章
C# StreamReader类和StreamWriter类
FileStream读写文件StreamWriter 和 StreamReader
从 .net core 2.1 与 .net core 3.0 调用时的 StreamWriter 类行为