有没有办法关闭一个 StreamWriter 而不关闭它的 BaseStream?

我的根本问题是,当 usingStreamWriter上调用 Dispose时,它也会处理 BaseStream(与 Close相同的问题)。

我有一个解决方案,但是正如您所看到的,它涉及到复制流。有没有办法在不复制流的情况下做到这一点?

这样做的目的是将字符串的内容(最初是从数据库读取的)放入流中,这样第三方组件就可以读取流。
注意: 我不能更改第三方组件。

public System.IO.Stream CreateStream(string value)
{
var baseStream = new System.IO.MemoryStream();
var baseCopy = new System.IO.MemoryStream();
using (var writer = new System.IO.StreamWriter(baseStream, System.Text.Encoding.UTF8))
{
writer.Write(value);
writer.Flush();
baseStream.WriteTo(baseCopy);
}
baseCopy.Seek(0, System.IO.SeekOrigin.Begin);
return baseCopy;
}

用作

public void Noddy()
{
System.IO.Stream myStream = CreateStream("The contents of this string are unimportant");
My3rdPartyComponent.ReadFromStream(myStream);
}

理想情况下,我在寻找一个名为 BreakAssociationWithBaseStream的假想方法,例如。

public System.IO.Stream CreateStream_Alternate(string value)
{
var baseStream = new System.IO.MemoryStream();
using (var writer = new System.IO.StreamWriter(baseStream, System.Text.Encoding.UTF8))
{
writer.Write(value);
writer.Flush();
writer.BreakAssociationWithBaseStream();
}
return baseStream;
}
49853 次浏览

如果使用.NET Framework 4.5或更高版本,则有一个 StreamWriter 重载,您可以使用它在关闭编写器时要求基流保持打开状态

在4.5之前的.NET Framework 的早期版本中,StreamWriter 假设拥有流。选项:

  • 不要处理 StreamWriter,冲掉它。
  • 创建一个流包装器,它忽略对 Close/Dispose的调用,但是代理其他所有内容。我在 MiscUtil中有一个这样的实现,如果您想从那里获取它的话。

只是不要在 StreamWriter上调用 Dispose。此类之所以是可抛弃的,并不是因为它持有非托管资源,而是因为它允许处置流,而流本身可以持有非托管资源。如果在其他地方处理基础流的生命周期,则不需要释放编写器。

你需要创建一个 StreamWriter 的后代并覆盖它的释放方法,通过总是向释放参数传递 false,它将强制流写入器不要关闭,StreamWriter 只是在 close 方法中调用 pose,所以没有必要覆盖它(当然你可以添加所有的构造函数,如果你想的话,我只有一个) :

public class NoCloseStreamWriter : StreamWriter
{
public NoCloseStreamWriter(Stream stream, Encoding encoding)
: base(stream, encoding)
{
}


protected override void Dispose(bool disposing)
{
base.Dispose(false);
}
}

内存流具有 ToArray 属性,即使在流关闭时也可以使用该属性。 数组将流内容写入字节数组,而不管 Position 属性如何。 您可以根据所写入的流创建新流。

public System.IO.Stream CreateStream(string value)
{
var baseStream = new System.IO.MemoryStream();
var baseCopy = new System.IO.MemoryStream();
using (var writer = new System.IO.StreamWriter(baseStream, System.Text.Encoding.UTF8))
{
writer.Write(value);
writer.Flush();
baseStream.WriteTo(baseCopy);
}
var returnStream = new System.IO.MemoryStream( baseCopy.ToArray());
return returnStream;
}

NET 4.5为此提供了一种新的方法:

StreamWriter (流,编码,Int32,Boolean)

public StreamWriter(
Stream stream,
Encoding encoding,
int bufferSize,
bool leaveOpen
)