Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot access a closed Stream of a memoryStream, how to reopen?

Tags:

c#

I have a memoryStream instance and it is closed.

I already have tried:

memoryStream.Flush();
memoryStream.Position=0;

To reopen the memory stream but it does not work. How can I reopen a closed memory stream?

like image 548
olidev Avatar asked Mar 01 '12 00:03

olidev


People also ask

How do I open memory stream?

MemoryStream creates streams that have memory as a backing store instead of a disk or a network connection. This can be useful in eliminating the need to write temporary files to disk or to store binary blob information in a database. To open or read file we use FileStream.

What is the difference between Stream and MemoryStream?

You would use the FileStream to read/write a file but a MemoryStream to read/write in-memory data, such as a byte array decoded from a string. You would not use a Stream in and of itself, but rather use it for polymorphism, i.e. passing it to methods that can accept any implementation of Stream as an argument.

How do I reuse MemoryStream?

You can re-use the MemoryStream by Setting the Position to 0 and the Length to 0. By setting the length to 0 you do not clear the existing buffer, it only resets the internal counters.


4 Answers

You can clone the original one and then use the clone, even when the original has been closed. Even though the original one is created with a capacity of 1000, ToArray() returns a 2 element array. ToBuffer() on the other hand gets you the entire buffer, which is what you don't want.

MemoryStream original = new MemoryStream(1000); original.WriteByte(4); original.WriteByte(5);  MemoryStream dolly = new MemoryStream(original.ToArray()); dolly.Seek(0, SeekOrigin.Begin); 
like image 91
Greg Biles Avatar answered Sep 20 '22 17:09

Greg Biles


try this:

memoryStream = new MemoryStream(memoryStream.ToArray()); 
like image 24
Andrew Pope Avatar answered Sep 22 '22 17:09

Andrew Pope


How can I reopen a closed memory stream?

You can't reopen the stream. If you need to "reset" the stream, just assign it a new instance:

memoryStream = new MemoryStream();
like image 30
Reed Copsey Avatar answered Sep 20 '22 17:09

Reed Copsey


This is an old, old question, but I'm reacting to the fact that the accepted answer isn't really useful and the highest-voted answer says that using .ToArray() is better than .GetBuffer(). I think that in many, perhaps most, situations using .GetBuffer() is significantly better than using .ToArray().

Here's an example of the problem of a memory stream getting closed despite your desire to continue using it:

  /// <summary>
  /// Method that gets called by ManagedResource.WriteData() in project CodeAnalysis during code 
  /// emitting to get the data for an embedded resource file.
  /// </summary>
  /// <param name="resourceFullFilename">full path and filename for resource file to embed</param>
  /// <returns>MemoryStream containing .resource file data - caller will dispose it</returns>
  private static MemoryStream ProvideResourceData(string resourceFullFilename)
  {
     MemoryStream shortLivedBackingStream = new MemoryStream();
     using (ResourceWriter resourceWriter = new ResourceWriter(shortLivedBackingStream))
     {
        using (ResXResourceReader resourceReader = new ResXResourceReader(resourceFullFilename))
        {
           IDictionaryEnumerator dictionaryEnumerator = resourceReader.GetEnumerator();
           while (dictionaryEnumerator.MoveNext())
           {
              string resourceKey = dictionaryEnumerator.Key as string;
              if (resourceKey != null)  // Should not be possible
                 resourceWriter.AddResource(resourceKey, dictionaryEnumerator.Value);
           }
        }
     }

     return new MemoryStream(shortLivedBackingStream.GetBuffer());
  }

The ResourceWriter class needs a backing stream so I give it a newly-created memory stream. But when ResourceWriter is no longer needed it closes the backing stream. Then I create a new MemoryStream based on the backing stream's buffer, which works fine, even though it is closed.

In this situation I happen to know that the calling program is going to use the provided memory stream to copy the data to another buffer and then close the memory stream immediately. So there is no need to create a new byte array, and there is a performance advantage to not creating a new byte array.

Thanks to @JoshVarty for showing how to avoid the problem of MemoryStream getting closed here: https://github.com/dotnet/roslyn/issues/7791

like image 36
RenniePet Avatar answered Sep 20 '22 17:09

RenniePet