Compress a single file using C#

user3362735 picture user3362735 · Jul 30, 2014 · Viewed 41.4k times · Source

I am using .NET 4.5, and the ZipFile class works great if I am trying to zip up an entire directory with "CreateFromDirectory". However, I only want to zip up one file in the directory. I tried pointing to a specific file (folder\data.txt), but that doesn't work. I considered the ZipArchive class since it has a "CreateEntryFromFile" method, but it seems this only allows you to create an entry into an existing file.

Is there no way to simply zip up one file without creating an empty zipfile (which has its issues) and then using the ZipArchiveExtension's "CreateEntryFromFile" method?

**This is also assuming I am working on a company program which cannot use third-party add-ons at the moment.

example from:http://msdn.microsoft.com/en-us/library/ms404280%28v=vs.110%29.aspx

        string startPath = @"c:\example\start";
        string zipPath = @"c:\example\result.zip";
        string extractPath = @"c:\example\extract";

        ZipFile.CreateFromDirectory(startPath, zipPath);

        ZipFile.ExtractToDirectory(zipPath, extractPath);

But if startPath were to be @"c:\example\start\myFile.txt;", it would throw an error that the directory is invalid.

Answer

John Koerner picture John Koerner · Jul 30, 2014

Use the CreateEntryFromFile off a an archive and use a file or memory stream:

Using a filestream if you are fine creating the zip file and then adding to it:

using (FileStream fs = new FileStream(@"C:\Temp\output.zip",FileMode.Create))
using (ZipArchive arch = new ZipArchive(fs, ZipArchiveMode.Create))
{
    arch.CreateEntryFromFile(@"C:\Temp\data.xml", "data.xml");
}

Or if you need to do everything in memory and write the file once it is done, use a memory stream:

using (MemoryStream ms = new MemoryStream())
using (ZipArchive arch = new ZipArchive(ms, ZipArchiveMode.Create))
{
    arch.CreateEntryFromFile(@"C:\Temp\data.xml", "data.xml");
}

Then you can write the MemoryStream to a file.

using (FileStream file = new FileStream("file.bin", FileMode.Create, System.IO.FileAccess.Write)) {
   byte[] bytes = new byte[ms.Length];
   ms.Read(bytes, 0, (int)ms.Length);
   file.Write(bytes, 0, bytes.Length);
   ms.Close();
}