Tuesday, October 26, 2010

Creating and Extracting a Zip File for Free

I could not find a free zip/unzip program on the web, so I had to create one myself.
Good guys here are at http://dotnetzip.codeplex.com that created a free zip library (Ionic.zip.dll) for us to use.

Using the Ionic library the program code for zipping and unzipping files is straightforward:

using System;
using System.IO;
using System.Text;
using Ionic.Zip;

namespace Zip
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                Usage();
                return;
            }

            if (args[0].StartsWith("z"))
            {
                Pack(args[1]);
            }
            else
            {
                UnPack(args[1]);
            }
        }

        static void Pack(string dir)
        {
            try
            {
                string dirRoot = Path.GetDirectoryName(dir);
                string dirName = Path.GetFileName(dir);
                string result = Path.Combine(dirRoot, dirName + ".zip");

                using (ZipFile zip = new ZipFile())
                {
                    zip.AddDirectory(dir, dirName);
                    zip.Save(result);
                }
                Console.WriteLine("Saved {0} to {1}", dir, result);
            }
            catch (Exception exc)
            {
                Console.WriteLine("Error packing: " + exc.Message);
                return;
            }
        }

        static void UnPack(string zipfile)
        {
            try
            {
                string dirRoot = Path.GetDirectoryName(zipfile);
                string dirName = Path.GetFileNameWithoutExtension(zipfile);
                string result = Path.Combine(dirRoot, dirName + "_extracted");

                using (ZipFile zip1 = ZipFile.Read(zipfile))
                {
                    foreach (ZipEntry e in zip1)
                    {
                        e.Extract(result, ExtractExistingFileAction.OverwriteSilently);
                    }
                }
                Console.WriteLine("Extracted {0} to {1}", zipfile, result);
            }
            catch (Exception exc)
            {
                Console.WriteLine("Error unpacking: " + exc.Message);
                return;
            }
        }

        static void Usage()
        {
            string exe = System.Reflection.Assembly.GetExecutingAssembly().Location;
            Console.WriteLine("Usage: {0} zip|unzip <directory|zip file>", exe);
            Console.WriteLine(" E.g.: {0} zip \"C:\\tmp\"", exe);
            Console.WriteLine(" E.g.: {0} unzip \"C:\\tmp\\myfile.zip\"", exe);

            Console.WriteLine();
            Console.WriteLine("Please press any key.");

            Console.ReadKey();
        }
    }
}


You can download this free zip/unzip program at http://www.nanogmail.com/Zip.zip and the dll from

Instructions:
  • Download Zip.zip and rename it to Zip.exe
  • Download Ionic.Zip.zip and rename it to Ionic.Zip.dll
  • Place Ionic.Zip.dll and Zip.exe to the same directory
  • Usage:
    • Zip.exe zip C:\directoryToZip
    • Zip.exe unzip C:\myzipfile.zip

You can also create and extract Zip files using standard .Net, but it is less straightforward.
Here is how to do that (add a reference to WindowsBase.dll in your project):


using System.IO;
using System.IO.Packaging;

namespace MyZip
{
    public class Zip
    {
        private static int _dataChunk = 1024;

        public static void CreateZipFile(string zipFile, string pathname)
        {
            using (Package zip = Package.Open(zipFile, FileMode.Create))
            {
                AddDirToZip(zip, pathname, "");
            }
        }

        public static void ExtractFromZipFile(string zipFile, string pathname)
        {
            using (Package zip = Package.Open(zipFile, FileMode.Open, FileAccess.Read))
            {
                foreach (PackagePart zipPart in zip.GetParts())
                {
                    Uri uri = zipPart.Uri;

                    string file = pathname + uri.OriginalString;
                    string dirName = Path.GetDirectoryName(file);

                    using (FileStream output = File.Create(file))
                    {
                        Stream input = zipPart.GetStream(FileMode.Open, FileAccess.Read);

                        byte[] buf = new byte[_dataChunk];
                        int bytes;

                        while (0 != (bytes = input.Read(buf, 0, _dataChunk)))
                        {
                            output.Write(buf, 0, bytes);
                        }

                        output.Close();
                    }
                }
            }
        }

        private static void AddDirToZip(Package zip, string pathname, string relDir)
        {
            foreach (string dir in Directory.GetDirectories(pathname))
            {
                string newRelDirName = relDir + Path.GetFileName(dir) + "\\";
                AddDirToZip(zip, dir, newRelDirName);
            }

            foreach (string file in Directory.GetFiles(pathname))
            {
                AddFileToZip(zip, file, relDir);
            }
        }

        private static void AddFileToZip(Package zip, string file, string relDir)
        {
            string filename = Path.GetFileName(file);
            string relPath = relDir + filename;
            Uri uri = PackUriHelper.CreatePartUri(new Uri(relPath, UriKind.Relative));
            PackagePart zipPart = zip.CreatePart(uri, System.Net.Mime.MediaTypeNames.Text.Plain);

            using (FileStream input = new FileStream(file,
                FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                Stream zipStream = zipPart.GetStream();

                byte[] buf = new byte[_dataChunk];
                int bytes;

                while (0 != (bytes = input.Read(buf, 0, _dataChunk)))
                {
                    zipStream.Write(buf, 0, bytes);
                }
            }
        }
    }
}

No comments:

Post a Comment