【发布时间】:2010-11-14 08:01:18
【问题描述】:
StreamWriter.Close() 表示它还关闭了 StreamWriter 的底层流。 StreamWriter.Dispose 呢? Dispose 是否也释放和/或关闭底层流
【问题讨论】:
StreamWriter.Close() 表示它还关闭了 StreamWriter 的底层流。 StreamWriter.Dispose 呢? Dispose 是否也释放和/或关闭底层流
【问题讨论】:
StreamWriter.Close() 只是在引擎盖下调用 StreamWriter.Dispose(),所以它们做的事情完全相同。 StreamWriter.Dispose() 确实关闭了底层流。
Reflector 是您的朋友,可以解答此类问题:)
【讨论】:
Stream.Close() 调用 Stream.Dispose(true),因此除非在实现类中重写此行为,否则它相当于同一件事。
有些人会说,不要dispose流,这是一个非常糟糕的主意,因为一旦streamwriter超出范围GarbageCollection可以随时拾取并dipose,从而关闭流的Handle,但是创建一个覆盖 StreamWriter 这种行为的后代类很简单,代码如下:
/// <summary>
/// Encapsulates a stream writer which does not close the underlying stream.
/// </summary>
public class NoCloseStreamWriter : StreamWriter
{
/// <summary>
/// Creates a new stream writer object.
/// </summary>
/// <param name="stream">The underlying stream to write to.</param>
/// <param name="encoding">The encoding for the stream.</param>
public NoCloseStreamWriter(Stream stream, Encoding encoding)
: base(stream, encoding)
{
}
/// <summary>
/// Creates a new stream writer object using default encoding.
/// </summary>
/// <param name="stream">The underlying stream to write to.</param>
/// <param name="encoding">The encoding for the stream.</param>
public NoCloseStreamWriter(Stream stream)
: base(stream)
{
}
/// <summary>
/// Disposes of the stream writer.
/// </summary>
/// <param name="disposing">True to dispose managed objects.</param>
protected override void Dispose(bool disposeManaged)
{
// Dispose the stream writer but pass false to the dispose
// method to stop it from closing the underlying stream
base.Dispose(false);
}
}
如果您查看 Reflector / ILSpy,您会发现基本流的关闭实际上是在 Dispose(true) 中完成的,当调用 close 时,它只调用调用 Dispose(True) 的 Dispose,从代码中应该没有其他副作用,所以上面的类工作得很好。
不过,您可能想添加所有构造函数,为了简单起见,我只是在此处添加了 2 个。
【讨论】:
StreamWriter 的终结器会调用Dispose(false),即不会处置BaseStream。我说会,因为StreamWriter 甚至没有终结器——因为它不需要终结器(它的终结器没有任何意义)。
来自 StreamWriter.Close()
public override void Close()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
来自 TextWriter.Dispose()(StreamWriter 继承)
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
因此,它们是相同的。
【讨论】:
Close 和 Dispose 是 StreamWriter 的同义词。
【讨论】:
引用 Cwalina 和 Abrams 在关于处置模式的部分中的 Framework Design Guidelines:
考虑提供方法
Close(),除了Dispose(),如果关闭是该领域的标准术语。
显然微软遵循他们自己的指导方针,并假设这对于 .NET 基类库来说几乎总是一个安全的选择。
【讨论】:
答案很简单,上面提供了:是的,处理流会关闭任何底层流。这是一个例子:
public static string PrettyPrintXML_bug(XDocument document)
{
string Result = "";
using (MemoryStream mStream = new MemoryStream())
{
using (XmlTextWriter writer = new XmlTextWriter(mStream, Encoding.Unicode))
{
writer.Formatting = Formatting.Indented; // <<--- this does the trick
// Write the XML into a formatting XmlTextWriter
document.WriteTo(writer);
// change the memory stream from write to read
writer.Flush();
mStream.Flush();
} // <-- <-- <-- <-- <-- <-- <-- <-- <-- <-- this also "closes" mStream
mStream.Position = 0;//rewind <-- <-- <-- "cannot Read/Write/Seek"
// Read MemoryStream contents into a StreamReader.
using (StreamReader sReader = new StreamReader(mStream)) // <-- <-- Exception: Cannot access a closed stream
{
// Extract the text from the StreamReader.
Result = sReader.ReadToEnd();
}
}
return Result;
}
这里是解决方案,您必须将 Dispose 延迟到不再需要底层 MemoryStream 的地方:
public static string PrettyPrintXML(XDocument document)
{
string Result = "";
using (MemoryStream mStream = new MemoryStream())
{
using (XmlTextWriter writer = new XmlTextWriter(mStream, Encoding.Unicode))
{
writer.Formatting = Formatting.Indented; // <<--- this does the trick
// Write the XML into a formatting XmlTextWriter
document.WriteTo(writer);
// change the memory stream from write to read
writer.Flush();
writer.Close();
mStream.Flush();
mStream.Position = 0;//rewind
// Read MemoryStream contents into a StreamReader.
using (StreamReader sReader = new StreamReader(mStream))
{
// Extract the text from the StreamReader.
Result = sReader.ReadToEnd();
}
}// <-- here the writer may be Disposed
}
return Result;
}
看了这些例子,我不明白为什么关闭底层流是一个特性。
我只是喜欢分享这个。
【讨论】: