Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. working around 'using wrapped MemoryStream immutability ?

working around 'using wrapped MemoryStream immutability ?

Scheduled Pinned Locked Moved C#
csharpmcpdata-structuresfunctionalperformance
4 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    BillWoodruff
    wrote on last edited by
    #1

    I can't do this because the MemoryStream is immutable: (code excerpt)

    using(MemoryStream mstream = new MemoryStream(File.ReadAllBytes(filepath)))
    {
    if (useDecryption)
    {
    mstream = decryptor(mstream);
    mstream.Position = 0;
    }

    if (useDecompression)
    {
        mstream = decompressor(mstream);
        mstream.Position = 0;
    }
    
    result = (T) dcs.ReadObject(mstream)   
    

    }

    So, okay, I can do this: (code excerpt)

    MemoryStream mstream = new MemoryStream(File.ReadAllBytes(filepath));

    if (useDecryption)
    {
    mstream = decryptor(mstream);
    mstream.Position = 0;
    }

    if (useDecompression)
    {
    mstream = decompressor(mstream);
    mstream.Position = 0;
    }

    result = (T) dcs.ReadObject(mstream);

    But that violates my early .NET memory-potty-training. Best/better practice ? Perhaps better to pass a byte array ? thanks, Bill

    «While I complain of being able to see only a shadow of the past, I may be insensitive to reality as it is now, since I'm not at a stage of development where I'm capable of seeing it. A few hundred years later another traveler despairing as myself, may mourn the disappearance of what I may have seen, but failed to see.» Claude Levi-Strauss (Tristes Tropiques, 1955)

    Richard DeemingR 1 Reply Last reply
    0
    • B BillWoodruff

      I can't do this because the MemoryStream is immutable: (code excerpt)

      using(MemoryStream mstream = new MemoryStream(File.ReadAllBytes(filepath)))
      {
      if (useDecryption)
      {
      mstream = decryptor(mstream);
      mstream.Position = 0;
      }

      if (useDecompression)
      {
          mstream = decompressor(mstream);
          mstream.Position = 0;
      }
      
      result = (T) dcs.ReadObject(mstream)   
      

      }

      So, okay, I can do this: (code excerpt)

      MemoryStream mstream = new MemoryStream(File.ReadAllBytes(filepath));

      if (useDecryption)
      {
      mstream = decryptor(mstream);
      mstream.Position = 0;
      }

      if (useDecompression)
      {
      mstream = decompressor(mstream);
      mstream.Position = 0;
      }

      result = (T) dcs.ReadObject(mstream);

      But that violates my early .NET memory-potty-training. Best/better practice ? Perhaps better to pass a byte array ? thanks, Bill

      «While I complain of being able to see only a shadow of the past, I may be insensitive to reality as it is now, since I'm not at a stage of development where I'm capable of seeing it. A few hundred years later another traveler despairing as myself, may mourn the disappearance of what I may have seen, but failed to see.» Claude Levi-Strauss (Tristes Tropiques, 1955)

      Richard DeemingR Offline
      Richard DeemingR Offline
      Richard Deeming
      wrote on last edited by
      #2

      Disposing a MemoryStream doesn't release any unmanaged resources. It simply sets some flags to indicate that future attempts to read or write the stream should throw an exception.

      protected override void Dispose(bool disposing)
      {
      try {
      if (disposing) {
      _isOpen = false;
      _writable = false;
      _expandable = false;
      // Don't set buffer to null - allow TryGetBuffer, GetBuffer & ToArray to work.
      #if FEATURE_ASYNC_IO
      _lastReadTask = null;
      #endif
      }
      }
      finally {
      // Call base.Close() to cleanup async IO resources
      base.Dispose(disposing);
      }
      }

      Reference Source[^] Despite the comment about the base method cleaning up async IO resources, it doesn't:

      protected virtual void Dispose(bool disposing)
      {
      // Note: Never change this to call other virtual methods on Stream
      // like Write, since the state on subclasses has already been
      // torn down. This is the last code to run on cleanup for a stream.
      }

      Reference Source[^] But I know what you mean - it doesn't feel right to omit the using statement. :) Perhaps a helper method to create the stream might help to hide the unpleasantness?

      private static MemoryStream CreateStream(byte[] rawBytes, IEnumerable<Func<MemoryStream, MemoryStream>> decorators)
      {
      var result = new MemoryStream(rawBytes);

      foreach (Func<MemoryStream, MemoryStream> decorator in decorators)
      {
          result = decorator(result);
          result.Position = 0;
      }
      
      return result;
      

      }

      ...

      var decorators = new List<Func<MemoryStream, MemoryStream>>();
      if (useDecryption) decorators.Add(decryptor);
      if (useDecompression) decorators.Add(decompressor);

      using (MemoryStream mstream = CreateStream(File.ReadAllBytes(filepath), decorators))
      {
      result = (T)dcs.ReadObject(mstream);
      }


      "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

      B 1 Reply Last reply
      0
      • Richard DeemingR Richard Deeming

        Disposing a MemoryStream doesn't release any unmanaged resources. It simply sets some flags to indicate that future attempts to read or write the stream should throw an exception.

        protected override void Dispose(bool disposing)
        {
        try {
        if (disposing) {
        _isOpen = false;
        _writable = false;
        _expandable = false;
        // Don't set buffer to null - allow TryGetBuffer, GetBuffer & ToArray to work.
        #if FEATURE_ASYNC_IO
        _lastReadTask = null;
        #endif
        }
        }
        finally {
        // Call base.Close() to cleanup async IO resources
        base.Dispose(disposing);
        }
        }

        Reference Source[^] Despite the comment about the base method cleaning up async IO resources, it doesn't:

        protected virtual void Dispose(bool disposing)
        {
        // Note: Never change this to call other virtual methods on Stream
        // like Write, since the state on subclasses has already been
        // torn down. This is the last code to run on cleanup for a stream.
        }

        Reference Source[^] But I know what you mean - it doesn't feel right to omit the using statement. :) Perhaps a helper method to create the stream might help to hide the unpleasantness?

        private static MemoryStream CreateStream(byte[] rawBytes, IEnumerable<Func<MemoryStream, MemoryStream>> decorators)
        {
        var result = new MemoryStream(rawBytes);

        foreach (Func<MemoryStream, MemoryStream> decorator in decorators)
        {
            result = decorator(result);
            result.Position = 0;
        }
        
        return result;
        

        }

        ...

        var decorators = new List<Func<MemoryStream, MemoryStream>>();
        if (useDecryption) decorators.Add(decryptor);
        if (useDecompression) decorators.Add(decompressor);

        using (MemoryStream mstream = CreateStream(File.ReadAllBytes(filepath), decorators))
        {
        result = (T)dcs.ReadObject(mstream);
        }


        B Offline
        B Offline
        BillWoodruff
        wrote on last edited by
        #3

        Thanks for another interesting, and challenging, response ! My "gut" is now telling me to switch to using byte-arrays wherever possible. Whether you gain anything (performance, memory economy) when shipping the raw data off to be encrypted and/or compressed by using a byte-array rather than a stream ... that's terra incognita to me :) ... but, I suspect that as I research the various tools that will come into focus. cheers, Bill

        «While I complain of being able to see only a shadow of the past, I may be insensitive to reality as it is now, since I'm not at a stage of development where I'm capable of seeing it. A few hundred years later another traveler despairing as myself, may mourn the disappearance of what I may have seen, but failed to see.» Claude Levi-Strauss (Tristes Tropiques, 1955)

        Richard DeemingR 1 Reply Last reply
        0
        • B BillWoodruff

          Thanks for another interesting, and challenging, response ! My "gut" is now telling me to switch to using byte-arrays wherever possible. Whether you gain anything (performance, memory economy) when shipping the raw data off to be encrypted and/or compressed by using a byte-array rather than a stream ... that's terra incognita to me :) ... but, I suspect that as I research the various tools that will come into focus. cheers, Bill

          «While I complain of being able to see only a shadow of the past, I may be insensitive to reality as it is now, since I'm not at a stage of development where I'm capable of seeing it. A few hundred years later another traveler despairing as myself, may mourn the disappearance of what I may have seen, but failed to see.» Claude Levi-Strauss (Tristes Tropiques, 1955)

          Richard DeemingR Offline
          Richard DeemingR Offline
          Richard Deeming
          wrote on last edited by
          #4

          The benefits would probably be more obvious if you were passing around the base Stream class. That way, your methods could work with anything stream-like, and wouldn't be limited to byte arrays.

          private static Stream DecorateStream(Stream input, IEnumerable<Func<Stream, Stream>> decorators)
          {
          Stream result = input;

          foreach (Func<Stream, Stream> decorator in decorators)
          {
              result = decorator(result);
          }
          
          return result;
          

          }

          ...

          var decorators = new List>();
          if (useDecryption) decorators.Add(decryptor);
          if (useDecompression) decorators.Add(decompressor);

          using (Stream input = DecorateStream(File.OpenRead(filePath), decorators)))
          {
          result = (T)dcs.ReadObject(input);
          }

          Now your code can work on the file in chunks, rather than having to read the whole thing into memory first.


          "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

          "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups