是否Stream.Dispose随时调用Stream.Close(和Stream.Flush)
题
如果我有以下的情况:
StreamWriter MySW = null;
try
{
Stream MyStream = new FileStream("asdf.txt");
MySW = new StreamWriter(MyStream);
MySW.Write("blah");
}
finally
{
if (MySW != null)
{
MySW.Flush();
MySW.Close();
MySW.Dispose();
}
}
我可以只需要调用MySW.Dispose()
并跳过关闭,即使它提供?是否有任何流implimentations预期不工作(就像CryptoStream的)?
如果不是,则是下面的只是坏代码:
using (StreamWriter MySW = new StreamWriter(MyStream))
{
MySW.Write("Blah");
}
解决方案
我可以只是调用MySW.Dispose()和 跳过关闭,即使它是 提供?
是的,这就是它的功能。
是否有任何流实现 如预期,不工作(像 CryptoStream的)?
它是安全的假设,如果一个对象实现IDisposable
,它会妥善处理本身。
如果没有,那么这将是一个错误。
如果不是,则在下面的只是坏 代码:
没有,该代码是处理实现IDisposable
对象的推荐的方式。
更多优秀的信息是在所接受的回答关闭和Dispose - 这打电话?
其他提示
我用反射器,发现System.IO.Stream.Dispose
看起来像这样:
public void Dispose()
{
this.Close();
}
如丹尼尔布鲁克纳提到的,处置和关闭是有效同样的事情。
然而流不调用Flush()它被设置时/关闭。的FileStream(我假定与一个高速缓存机制的任何其他流),其设置时不会调用flush()。
如果设置时要扩展流,或MemoryStream的等你将需要实现一个呼叫到冲洗()/关闭,如果它是必要的。
两者StreamWriter.Dispose()和Stream.Dispose()释放由对象保持的所有资源。两者关闭基础流。
Stream.Dispose()的源代码(注意,这是实施细节,以便不依赖于它):
public void Dispose()
{
this.Close();
}
StreamWriter.Dispose()(同与Stream.Dispose()):
protected override void Dispose(bool disposing)
{
try
{
// Not relevant things
}
finally
{
if (this.Closable && (this.stream != null))
{
try
{
if (disposing)
{
this.stream.Close();
}
}
finally
{
// Not relevant things
}
}
}
}
不过,我通常隐含接近流/ streamwriters处置他们面前 - 我认为它看起来更清洁
。所有标准流(的FileStream,CryptoStream的)将试图关闭/设置何时刷新。我想你可以靠这个对于任何微软流实现。
其结果,关闭/处置可以如果冲洗失败抛出异常。
在事实上IIRC有在它会失败,如果在冲洗抛出异常来释放文件句柄.NET 1.0实现的FileStream的一个错误。这通过将固定在.NET 1.1 try / finally块到的Dispose(boolean)方法
有关需要被手动关闭对象,每次应努力以创建在一个使用块的对象。
//Cannot access 'stream'
using (FileStream stream = File.Open ("c:\\test.bin"))
{
//Do work on 'stream'
} // 'stream' is closed and disposed of even if there is an exception escaping this block
// Cannot access 'stream'
在这种方式一个永远不能错误地访问“流” out所使用的子句的上下文和文件总是关闭。
我在Stream类的.NET源看去,它有哪些建议以下,是的,你可以...
// Stream used to require that all cleanup logic went into Close(),
// which was thought up before we invented IDisposable. However, we
// need to follow the IDisposable pattern so that users can write
// sensible subclasses without needing to inspect all their base
// classes, and without worrying about version brittleness, from a
// base class switching to the Dispose pattern. We're moving
// Stream to the Dispose(bool) pattern - that's where all subclasses
// should put their cleanup starting in V2.
public virtual void Close()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose()
{
Close();
}
Stream.Close
是通过调用实现为Stream.Dispose
或反之亦然 - 这样的方法是等效的。 Stream.Close
存在只是因为关闭流听起来比设置一个流更自然。
除此之外,您还应该尽量避免这种方法的显式调用和使用using
声明,而不是为了得到正确的异常处理是免费的。