C# Stream.Dispose 是否总是调用 Stream.Close(和 Stream.Flush)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/911408/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does Stream.Dispose always call Stream.Close (and Stream.Flush)
提问by JasonRShaver
If I have the following situation:
如果我有以下情况:
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();
}
}
Can I just call MySW.Dispose()
and skip the Close even though it is provided? Are there any Stream implimentations that don't work as expected (Like CryptoStream)?
MySW.Dispose()
即使提供了关闭,我也可以直接调用并跳过关闭吗?是否有任何 Stream 实现无法按预期工作(如 CryptoStream)?
If not, then is the following just bad code:
如果没有,那么以下只是糟糕的代码:
using (StreamWriter MySW = new StreamWriter(MyStream))
{
MySW.Write("Blah");
}
采纳答案by Binary Worrier
Can I just call MySW.Dispose() and skip the Close even though it is provided?
我可以只调用 MySW.Dispose() 并跳过关闭,即使它提供了吗?
Yes, that's what it's for.
是的,这就是它的用途。
Are there any Stream implementations that don't work as expected (Like CryptoStream)?
是否有任何 Stream 实现无法按预期工作(如 CryptoStream)?
It is safe to assume that if an object implements IDisposable
, it will dispose of itself properly.
可以安全地假设,如果一个对象实现了IDisposable
,它将正确地处理自己。
If it doesn't, then that would be a bug.
如果没有,那么这将是一个错误。
If not, then is the following just bad code:
如果没有,那么以下只是糟糕的代码:
No, that code is the recommended way of dealing with objects that implement IDisposable
.
不,该代码是处理实现IDisposable
.
More excellent information is in the accepted answer to Close and Dispose - which to call?
更多优秀信息在Close and Dispose的公认答案中- 调用哪个?
回答by Andrew Hare
I used Reflector and found that System.IO.Stream.Dispose
looks like this:
我使用了 Reflector,发现它System.IO.Stream.Dispose
看起来像这样:
public void Dispose()
{
this.Close();
}
回答by Daniel Brückner
Stream.Close
is implemented by a call to Stream.Dispose
or vice versa - so the methods are equivalent. Stream.Close
exists just because closing a stream sounds more natural than disposing a stream.
Stream.Close
是通过调用来实现的,Stream.Dispose
反之亦然 - 所以这些方法是等效的。Stream.Close
存在只是因为关闭流听起来比处理流更自然。
Besides you should try to avoid explicit calls to this methods and use the using
statement instead in order to get correct exception handling for free.
此外,您应该尽量避免显式调用此方法并改用该using
语句,以便免费获得正确的异常处理。
回答by Tamas Czinege
Both StreamWriter.Dispose() and Stream.Dispose() release all resources held by the objects. Both of them close the underlying stream.
StreamWriter.Dispose() 和 Stream.Dispose() 都释放对象持有的所有资源。它们都关闭了底层流。
The source code of Stream.Dispose() (note that this is implementation details so don't rely on it):
Stream.Dispose() 的源代码(注意这是实现细节所以不要依赖它):
public void Dispose()
{
this.Close();
}
StreamWriter.Dispose() (same as with Stream.Dispose()):
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
}
}
}
}
Still, I usually implicitly close streams/streamwriters before disposing them - I think it looks cleaner.
尽管如此,我通常会在处理流/流编写器之前隐式关闭它们 - 我认为它看起来更干净。
回答by Joe
All standard Streams (FileStream, CryptoStream) will attempt to flush when closed/disposed. I think you can rely on this for any Microsoft stream implementations.
所有标准流(FileStream、CryptoStream)将在关闭/处置时尝试刷新。我认为您可以将其用于任何 Microsoft 流实现。
As a result, Close/Dispose can throw an exception if the flush fails.
因此,如果刷新失败,Close/Dispose 可能会引发异常。
In fact IIRC there was a bug in the .NET 1.0 implementation of FileStream in that it would fail to release the file handle if the flush throws an exception. This was fixed in .NET 1.1 by adding a try/finally block to the Dispose(boolean) method.
事实上,IIRC 在 FileStream 的 .NET 1.0 实现中存在一个错误,即如果刷新引发异常,它将无法释放文件句柄。这在 .NET 1.1 中通过向 Dispose(boolean) 方法添加 try/finally 块来修复。
回答by ScottS
As Daniel Bruckner mentioned, Dispose and Close are effectively the same thing.
正如 Daniel Bruckner 所提到的,Dispose 和 Close 实际上是一回事。
However Stream does NOT call Flush() when it is disposed/closed. FileStream (and I assume any other Stream with a caching mechanism) does call Flush() when disposed.
但是,Stream 在处理/关闭时不会调用 Flush()。FileStream(我假设任何其他具有缓存机制的 Stream)在处理时会调用 Flush()。
If you are extending Stream, or MemoryStream etc. you will need to implement a call to Flush() when disposed/closed if it is necessary.
如果您要扩展 Stream 或 MemoryStream 等,则需要在处置/关闭时实现对 Flush() 的调用(如有必要)。
回答by clemahieu
For objects that need to be manually closed, every effort should be made to create the object in a using block.
对于需要手动关闭的对象,应尽一切努力在 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'
In this way one can never incorrectly access 'stream' out of the context of the using clause and the file is always closed.
通过这种方式,人们永远不会在 using 子句的上下文之外错误地访问“流”,并且文件始终处于关闭状态。
回答by Steve Sheldon
I looked in the .net source for the Stream class, it had the following which would suggest that yes you can...
我查看了 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();
}