title: Avoiding MemoryStream.ToArray() when using System.IO.Compression.ZipArchive
body: <p>A helper method to turn a string into a zipped up text file:</p>
  
  <pre><code>public static System.Net.Mail.Attachment CreateZipAttachmentFromString(string content, string filename)
  {
    using (MemoryStream memoryStream = new MemoryStream())
    {
      using (ZipArchive zipArchive = new ZipArchive(memoryStream, ZipArchiveMode.Update))
      {
        ZipArchiveEntry zipArchiveEntry = zipArchive.CreateEntry(filename);
        using (StreamWriter streamWriter = new StreamWriter(zipArchiveEntry.Open()))
        {
          streamWriter.Write(content);
        }
  
      }
  
      MemoryStream memoryStream2 = new MemoryStream(memoryStream.ToArray(), false);
  
      return new Attachment(memoryStream2, filename + ".zip", MediaTypeNames.Application.Zip);
    }
  }
  </code></pre>
  
  <p>I was really hoping to avoid turning the first memory stream into an array, making another memory stream on it to read it, and passing that to attachment. My logic was, why copy X megabytes to another place in memory to establish another stream pointing to the copy, when it's essentially just what we started out with.. It's the multi-megabyte equivalent of redundancy like <code>if(myBool == true)</code> </p>
  
  <p>So I figured instead I would Seek back to the start of the first memory stream, and then attachment could just read that.. Or I would establish another memorystream pointing to the buffer of the first, and with the offset and length parameters set so it would know what to read</p>
  
  <p>Neither of these approaches work out because it seems that ZipArchive only pushes data into the memory stream (in my case maybe) when control falls out of the using block and the ziparchive is disposed. Disposing it also disposes the MemoryStream and nearly everything (other than ToArray() and GetBuffer()) throw ObjectDisposedException. </p>
  
  <p>Ultimately I can't seek it or get its length after the ZipArchive pumps data into it and before it pumps it in, the offset is usually zero and the length is definitely zero so the values are useless</p>
  
  <p>Is there a nice optimal way, short of configuring my own over-large buffer (which then makes it non expandable by MemoryStream), to avoid having to burn up around 2x the memory bytes of the archive size with this method?</p>