如果我有以下情况:
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()
并跳过关闭,即使提供了吗?是否存在任何不能按预期工作的Stream implament(如CryptoStream)?
如果没有,那么以下只是错误的代码:
using (StreamWriter MySW = new StreamWriter(MyStream))
{
MySW.Write("Blah");
}
答案 0 :(得分:80)
我可以调用MySW.Dispose()和 跳过关闭,即使它是 提供?
是的,这就是它的用途。
是否有任何Stream实现 不能按预期工作(喜欢 CryptoStream的)?
可以安全地假设,如果一个对象实现IDisposable
,它将正确处理它。
如果没有,则那将是一个错误。
如果没有,那么以下就是坏事 代码:
不,该代码是处理实现IDisposable
的对象的推荐方法。
答案 1 :(得分:58)
我使用了Reflector,发现System.IO.Stream.Dispose
看起来像这样:
public void Dispose()
{
this.Close();
}
答案 2 :(得分:21)
Daniel Bruckner提到,Dispose和Close实际上是一回事。
然而,Stream在处理/关闭时不会调用Flush()。 FileStream(我假设任何其他具有缓存机制的Stream)在处理时调用Flush()。
如果您正在扩展Stream或MemoryStream等,则需要在处理/关闭时执行对Flush()的调用。
答案 3 :(得分:3)
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 - 我觉得它看起来更干净。
答案 4 :(得分:3)
所有标准Streams(FileStream,CryptoStream)将在关闭/处置时尝试刷新。我认为你可以依赖于任何Microsoft流实现。
因此,如果刷新失败,Close / Dispose会抛出异常。
事实上,IIRC在FileStream的.NET 1.0实现中存在一个错误,如果flush抛出异常,它将无法释放文件句柄。通过在Dispose(boolean)方法中添加try / finally块,可以在.NET 1.1中修复此问题。
答案 5 :(得分:3)
对于需要手动关闭的对象,应尽一切努力在using块中创建对象。
//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'
通过这种方式,人们永远不会错误地从using子句的上下文中访问'stream',并且文件总是被关闭。
答案 6 :(得分:3)
我查看了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();
}
答案 7 :(得分:2)
Stream.Close
是通过调用Stream.Dispose
实现的,反之亦然 - 因此方法是等效的。 Stream.Close
的存在只是因为关闭流听起来比处理流更自然。
此外,您应该尝试避免显式调用此方法并使用using
语句,以便免费获得正确的异常处理。