简体   繁体   English

MemoryStream的麻烦

[英]MemoryStream troubles

I'm having some trouble using a MemoryStream 我在使用MemoryStream时遇到了一些麻烦

We're using a 3rd party spreadsheet component (similar to excel), and I'm trying to save the data as html which they support through the SaveHtml method below. 我们使用的是第三方电子表格组件(类似于excel),并且我试图通过下面的SaveHtml方法将数据保存为html,它们支持。 Seems very simple based on their documentation. 根据他们的文档看来很简单。 Here is my code: 这是我的代码:

using (var memoryStream = new MemoryStream())
{
   this.ActiveSheet.SaveHtml(memoryStream);

   memoryStream.Position = 0;

   using (var streamReader = new StreamReader(memoryStream))
   {
       var htmlData = streamReader.ReadToEnd();
   }
}

I get an exception when I set the memoryStream.Position = 0 : 设置memoryStream.Position = 0时出现异常:

System.ObjectDisposedException: Cannot access a closed Stream.

A quick look at their SaveHtml method in Reflector shows the following relevant lines: 快速查看他们在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();
        }
    }
}

I'm guessing because the streamWriter is closed by their code, we're out of luck. 我猜是因为streamWriter被他们的代码关闭了,所以我们很不走运。 Closing the streamWriter, closes the underlying Stream, right? 关闭streamWriter,关闭基础Stream,对吗?

Any way to get around this? 有什么办法解决这个问题?

Thanks. 谢谢。

It seems it works, so you can create another memory stream. 似乎可以,所以您可以创建另一个内存流。 No bytes are copied when extracting the buffer. 提取缓冲区时,不复制任何字节。

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();
    }
}

Or you can roll out your own uncloseable MemoryStream and feed it to SaveHtml. 或者,您可以推出自己无法关闭的MemoryStream,并将其提供给SaveHtml。 This will also prevent disposing it, since Dispose just calls Close. 这也将阻止处理它,因为Dispose仅调用Close。 Again, imho: 再次,恕我直言:

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

Alternative memory stream implementation can be used in such context: 可以在以下情况下使用备用内存流实现:

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM