内存流故障



我在使用MemoryStream 时遇到一些问题

我们使用的是第三方电子表格组件(类似于excel),我试图通过下面的SaveHtml方法将数据保存为html。根据他们的文档,看起来很简单。这是我的代码:

using (var memoryStream = new MemoryStream())
{
   this.ActiveSheet.SaveHtml(memoryStream);
   memoryStream.Position = 0;
   using (var streamReader = new StreamReader(memoryStream))
   {
       var htmlData = streamReader.ReadToEnd();
   }
}

设置memoryStream.Position = 0:时出现异常

System.ObjectDisposedException: Cannot access a closed Stream.

在Reflector中快速查看他们的SaveHtml方法显示了以下相关行:

public void SaveHtml(Stream stream)
{
    StreamWriter writer = null;
    try
    {
        writer = new StreamWriter(stream) { AutoFlush = true };
        writer.Write(str);
    }   
    finally
    {
        if (writer != null)
        {
            writer.Close();
        }
    }
}

我猜因为streamWriter被他们的代码关闭了,我们运气不好了。关闭streamWriter,就会关闭底层Stream,对吧?

有办法绕过这个吗?

谢谢。

它似乎可以工作,所以您可以创建另一个内存流。提取缓冲区时不会复制任何字节。

using (var memoryStream = new MemoryStream()) {
    this.ActiveSheet.SaveHtml(memoryStream);
    var buffer = memoryStream.GetBuffer();
    using (var memoryStream2 = new MemoryStream(buffer))
    using (var streamReader = new StreamReader(memoryStream2)) {
        var htmlData = streamReader.ReadToEnd();
    }
}

或者,您可以推出自己的不可复制的MemoryStream并将其提供给SaveHtml。这也将阻止处理它,因为Dispose只调用Close。再次,imho:

class MemoryStream2 : MemoryStream {
    public override void Close() { }
}

在这样的上下文中可以使用替代的内存流实现:

var stream = new ChunkedStream(pool, asOutputStreamOnDispose: true);
using (var writer = new StreamWriter(stream))
{
    writer.Write("hello world");
}
Assert.AreEqual(0, stream.Position);
Assert.AreEqual(ChunkedStreamState.ReadForward, stream.State);
Assert.AreEqual(3, pool.TotalAllocated);
using (var reader = new StreamReader(stream))
{
    Assert.AreEqual("hello world", reader.ReadToEnd());
    Assert.AreEqual(0, pool.TotalAllocated);
}
Assert.AreEqual(ChunkedStreamState.Closed, stream.State);

相关内容

  • 没有找到相关文章

最新更新