我的根本问题是当using
在Dispose
上调用StreamWriter
时,它还会处理BaseStream
(与Close
相同的问题)。
我有一个解决方法,但正如您所看到的,它涉及复制流。有没有办法在不复制流的情况下这样做?
这样做的目的是将字符串(最初从数据库中读取)的内容放入流中,以便第三方组件可以读取该流。 NB :我无法更改第三方组件。
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;
}
答案 0 :(得分:104)
如果您使用的是.NET Framework 4.5或更高版本,则会有StreamWriter overload using which you can ask the base stream to be left open when the writer is closed。
在4.5之前的早期版本的.NET Framework中,StreamWriter
假设它拥有该流。选项:
StreamWriter
;只是冲洗它。Close
/ Dispose
的调用,但代理其他所有内容。我在MiscUtil中有一个实现,如果你想从那里抓住它。答案 1 :(得分:40)
.NET 4.5为此获得了新的方法!
http://msdn.microsoft.com/EN-US/library/gg712853(v=VS.110,d=hv.2).aspx
public StreamWriter(
Stream stream,
Encoding encoding,
int bufferSize,
bool leaveOpen
)
答案 2 :(得分:32)
只是不要在Dispose
上致电StreamWriter
。这个类是一次性的原因不是因为它拥有非托管资源,而是允许处理本身可能拥有非托管资源的流。如果底层流的生命在其他地方处理,则不需要处理编写器。
答案 3 :(得分:5)
内存流具有ToArray属性,即使在关闭流时也可以使用该属性。 无论Position属性如何,To Array都将流内容写入字节数组。 您可以根据您编写的流创建新流。
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;
}
答案 4 :(得分:1)
你需要创建StreamWriter的后代并覆盖它的dispose方法,总是将false传递给disposing参数,它会强制流编写器不关闭,StreamWriter只是在close方法中调用dispose,所以有不需要覆盖它(当然,如果你愿意,你可以添加所有构造函数,我只需要一个):
public class NoCloseStreamWriter : StreamWriter
{
public NoCloseStreamWriter(Stream stream, Encoding encoding)
: base(stream, encoding)
{
}
protected override void Dispose(bool disposing)
{
base.Dispose(false);
}
}