简体   繁体   中英

MemoryStream troubles

I'm having some trouble using a 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. 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 :

System.ObjectDisposedException: Cannot access a closed Stream.

A quick look at their SaveHtml method in Reflector shows the following relevant lines:

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. Closing the streamWriter, closes the underlying Stream, right?

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. This will also prevent disposing it, since Dispose just calls 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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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