Zip and unzip a string of data in memory

I was looking for a way to zip and unzip a file.

Normally, this is not really an issue. There are lots of libraries and NuGet packages available.

But this file was represented to me as a string, some JSON, actually.

So I was looking for a way to convert a string into some zipped format and back. This was harder than expected.

In the end, I wrote a solution myself. Here it is for you to use it, just to save you a lot of time.

Note: This library is available on GitHub. And Visual Studio users can import the NuGet package.

I tried several NuGet libraries but all failed to just zip and unzip a MemoryStream. Once I managed to zip the stream using a library but the way back was impossible without the use of some kind of file system.

Finally, I was pointed to the ‘old’ System.IO.Compression library. And this gave me the solution:

/// <summary>
/// Zip and Unzip in memory using System.IO.Compression.
/// </summary>
/// <remarks>
/// Include System.IO.Compression in your project.
/// </remarks>
public static class ZipHelper
{
  /// <summary>
  /// Zips a string into a zipped byte array.
  /// </summary>
  /// <param name="textToZip">The text to be zipped.</param>
  /// <returns>byte[] representing a zipped stream</returns>
  public static byte[] Zip(string textToZip)
  {
    using (var memoryStream = new MemoryStream())
    {
      using (var zipArchive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
      {
        var demoFile = zipArchive.CreateEntry("zipped.txt");

        using (var entryStream = demoFile.Open())
        {
          using (var streamWriter = new StreamWriter(entryStream))
          {
            streamWriter.Write(textToZip);
          }
        }
      }

      return memoryStream.ToArray();
    }
  }

  /// <summary>
  /// Unzip a zipped byte array into a string.
  /// </summary>
  /// <param name="zippedBuffer">The byte array to be unzipped</param>
  /// <returns>string representing the original stream</returns>
  public static string Unzip(byte[] zippedBuffer)
  {
    using (var zippedStream = new MemoryStream(zippedBuffer))
    {
      using (var archive = new ZipArchive(zippedStream))
      {
        var entry = archive.Entries.FirstOrDefault();

        if (entry != null)
        {
          using (var unzippedEntryStream = entry.Open())
          {
            using (var ms = new MemoryStream())
            {
              unzippedEntryStream.CopyTo(ms);
              var unzippedArray = ms.ToArray();

              return Encoding.Default.GetString(unzippedArray);
            }
          }
        }

        return null;
      }
    }
  }
}

So you only need to reference this ‘System.IO.Compression’ reference in your Visual Studio project.

How to test this library?

Testing is easy, just pick a file:

class Program
{
  static void Main(string[] args)
  {
    //// 1. Read file from disk and text. So text is our input

    var fileName = @"C:\dev\filewithtexttocompress.txt";
    var textBuffer = File.ReadAllText(fileName);

    //// 2. ZIP IN MEMORY. Create zipped byte array from string

    var zippedBuffer = ZipHelper.Zip(textBuffer);

    //// 3. write byte array to zip file

    var zipName = @"C:\dev\filewithtexttocompress.zip";
    File.WriteAllBytes(zipName, zippedBuffer);

    //// 4. read zip from file into byte array

    var rawFileStream = File.OpenRead(zipName);
    byte[] zippedtoTextBuffer = new byte[rawFileStream.Length];
    rawFileStream.Read(zippedtoTextBuffer, 0, (int) rawFileStream.Length);

    //// 5. UNZIP IN MEMORY. Create text from zipped byte array

    var text = ZipHelper.Unzip(zippedtoTextBuffer);

    //// 6. Write unzipped file

    File.WriteAllText(@"C:\dev\unzipped.txt", text);
  }
}

Just pass a file to test the zip/unzip helper. No, we do not need actual files but it’s is easy to cope with large texts.

Remember: this helper class only supports the input of ONE text. If you need to zip multiple texts, you have to change the code. It’s not that hard, just keep in mind a ZIP format is thinking in separate files…

Conclusion

Yes, you can now zip and unzip in memory, without the use of (temporary) files.

Advertenties

Een reactie op “Zip and unzip a string of data in memory

Reacties zijn gesloten.