StreamWriter.Close()表示它还会关闭StreamWriter的基础流。那么StreamWriter.Dispose呢? Dispose是否也处置和/或关闭基础流
答案 0 :(得分:49)
StreamWriter.Close()只是在引擎盖下调用StreamWriter.Dispose(),所以它们完全相同。 StreamWriter.Dispose()会关闭基础流。
Reflector是您这样的问题的朋友:)
答案 1 :(得分:15)
有些人会说,只是不要处理流,这是一个非常糟糕的主意,因为一旦编写器超出范围,GarbageCollection可以随时拾取并放弃它,从而关闭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调用Dispose(True),从代码那里应该没有其他副作用,所以上面的课程效果很好。
你可能想要添加所有的构造函数,为了简单起见,我刚刚添加了2。
答案 2 :(得分:13)
来自StreamWriter.Close()
public override void Close()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
来自TextWriter.Dispose()(StreamWriter继承)
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
因此,它们完全相同。
答案 3 :(得分:6)
Close和Dispose是StreamWriter的同义词。
答案 4 :(得分:2)
引用Cwalina和Abrams关于处置模式的框架设计指南:
CONSIDER 除了
Close()
之外,还提供方法Dispose()
,如果close是该区域的标准术语。
显然,微软遵循他们自己的指导方针,并且假设这对于.NET基类库几乎总是一个安全的选择。
答案 5 :(得分:1)
答案很简单,并在上面提供:是的,处理流会关闭任何底层流。这是一个例子:
struct lambda_caller
{
boost::optional<lambda> _lambda;
~lambda_caller()
{
if (_lambda) {
(*_lambda)();
_lambda = boost::none;
}
}
void release() {
_lambda = boost::none;
}
};
这里是解决方案,你必须将Dispose延迟到不再需要底层MemoryStream的地方了:
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;
}
看看这些例子,我不明白为什么关闭底层流是一个功能。
我只是喜欢分享这个。