Click here to Skip to main content
15,891,943 members
Articles / Programming Languages / XML

Zip/Unzip using the java.util.zip .NET namespace and more

Rate me:
Please Sign up or sign in to vote.
4.49/5 (17 votes)
12 Feb 2013CPOL5 min read 162.6K   3K   70  
Zip/Unzip using java.util.zip from managed code.
/*
 * CPZipStripper 2.0
 * Written by Decebal Mihailescu [http://www.codeproject.com/script/articles/list_articles.asp?userid=634640]
*/
using System;
using System.Collections.Generic;
using System.Text;
using java.util.zip;
using System.IO;
using System.Security;
using System.Security.Cryptography;
using System.Runtime.InteropServices;

namespace CPZipStripper
{
    static class ZipUtility
    {
        static private string m_zipFolder;
        static private ZipOutputStream _zos = null;
        static private int m_trimIndex = 0;
        static private sbyte[] _buffer = new sbyte[2048];
        //  Call this function to remove the key from memory after use for security
        [System.Runtime.InteropServices.DllImport("KERNEL32.DLL", EntryPoint = "RtlZeroMemory")]
        internal static extern bool ZeroMemory(IntPtr Destination, int Length);
        #region cryptograhy
        //// Function to Generate a 64 bits Key.
        //static string GenerateKey()
        //{
        //    //DESCryptoServiceProvider DES = new DESCryptoServiceProvider();

        //    // Create an instance of Symetric Algorithm. Key and IV is generated automatically.
        //    DESCryptoServiceProvider desCrypto = (DESCryptoServiceProvider)DESCryptoServiceProvider.Create();

        //    // Use the Automatically generated key for Encryption. 
        //    return ASCIIEncoding.ASCII.GetString(desCrypto.Key);
        //}
        //static void EncryptFile(string sInputFilename,
        //   string sOutputFilename,
        //   string sKey)
        //{
        //    FileStream fsInput = new FileStream(sInputFilename,
        //       FileMode.Open,
        //       FileAccess.Read);

        //    FileStream fsEncrypted = new FileStream(sOutputFilename,
        //       FileMode.Create,
        //       FileAccess.Write);
        //    DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
        //    DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
        //    DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
        //    ICryptoTransform desencrypt = DES.CreateEncryptor();
        //    CryptoStream cryptostream = new CryptoStream(fsEncrypted,
        //       desencrypt,
        //       CryptoStreamMode.Write);

        //    byte[] bytearrayinput = new byte[fsInput.Length];
        //    fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
        //    cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
        //    cryptostream.Close();
        //    fsInput.Close();
        //    fsEncrypted.Close();
        //}

        //static void DecryptFile(string sInputFilename,
        //   string sOutputFilename,
        //   string sKey)
        //{
        //    DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
        //    //A 64 bit key and IV is required for this provider.
        //    //Set secret key For DES algorithm.
        //    DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
        //    //Set initialization vector.
        //    DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);

        //    //Create a file stream to read the encrypted file back.
        //    FileStream fsread = new FileStream(sInputFilename,
        //       FileMode.Open,
        //       FileAccess.Read);
        //    //Create a DES decryptor from the DES instance.
        //    ICryptoTransform desdecrypt = DES.CreateDecryptor();
        //    //Create crypto stream set to read and do a 
        //    //DES decryption transform on incoming bytes.
        //    CryptoStream cryptostreamDecr = new CryptoStream(fsread,
        //       desdecrypt,
        //       CryptoStreamMode.Read);
        //    //Print the contents of the decrypted file.
        //    StreamWriter fsDecrypted = new StreamWriter(sOutputFilename);
        //    fsDecrypted.Write(new StreamReader(cryptostreamDecr).ReadToEnd());
        //    fsDecrypted.Flush();
        //    fsDecrypted.Close();
        //}

        //static void TestEncryptDecrypt()
        //{
        //    string s = "Foo bar";
        //    string s1 = Convert.ToBase64String(Encoding.Unicode.GetBytes(s));

        //    // And back...
        //    string s2 = Encoding.Unicode.GetString(Convert.FromBase64String(s1));
        //    // Must be 64 bits, 8 bytes.
        //    // Distribute this key to the user who will decrypt this file.
        //    string sSecretKey;

        //    // Get the Key for the file to Encrypt.
        //    sSecretKey = GenerateKey();

        //    // For additional security Pin the key.
        //    GCHandle gch = GCHandle.Alloc(sSecretKey, GCHandleType.Pinned);

        //    // Encrypt the file.        
        //    EncryptFile(@"C:\MyData.txt",
        //       @"C:\Encrypted.txt",
        //       sSecretKey);

        //    // Decrypt the file.
        //    DecryptFile(@"C:\Encrypted.txt",
        //       @"C:\Decrypted.txt",
        //       sSecretKey);

        //    // Remove the Key from memory. 
        //    ZeroMemory(gch.AddrOfPinnedObject(), sSecretKey.Length * 2);
        //    gch.Free();
        //}
        #endregion
        public static List<string> GetZipFileNames(string zipFile)
        {
            ZipFile zf = null;
            List<string> list = new List<string>();
            try
            {
                zf = new ZipFile(zipFile);
                java.util.Enumeration enu = zf.entries();
                while (enu.hasMoreElements())
                {
                    ZipEntry zen = enu.nextElement() as ZipEntry;
                    if (zen.isDirectory())
                        continue;//ignore directories
                    list.Add(zen.getName());
                    System.Windows.Forms.Application.DoEvents();
                }

            }
            catch(Exception ex) 
            {
                throw new ApplicationException("Please drag/drop only valid zip files\nthat are not password protected.",ex);
            }
            finally
            {
                if (zf != null)
                    zf.close();               
            }
            return list;
        }


        public static void CreateZipFromFolder(string Folder, IsFileStrippableDelegate IsStrip)
        {
            try
            {
                string ParentDir = Directory.GetParent(Folder).FullName;
                m_trimIndex = ParentDir.Length;
                string root = Path.GetPathRoot(Folder);
                if (ParentDir != root)
                    m_trimIndex++;
                m_zipFolder = Folder;
                string strNewFile = m_zipFolder + ".zip";
                string fileName = Path.GetFileName(strNewFile);
                strNewFile = Path.GetDirectoryName(strNewFile) + @"\" + fileName;
                //make room for the new zip
                System.IO.File.Delete(strNewFile + ".old");
                if (File.Exists(strNewFile))
                    System.IO.File.Move(strNewFile, strNewFile + ".old");
                _zos = new ZipOutputStream(new java.io.FileOutputStream(strNewFile));
                _CreateZipFromFolder(Folder, IsStrip);
            }//try ends
            catch (Exception ex)
            {
                throw new ApplicationException("unable to zip " + Folder + "folder", ex);
             }
            finally
            {
                if (_zos != null)
                    _zos.close();
                _zos = null;
                m_trimIndex = 0;
            }

        }
        private static void _CreateZipFromFolder(string Folder, IsFileStrippableDelegate IsStrip)
        {

            System.IO.DirectoryInfo dirInfo =
                new System.IO.DirectoryInfo(Folder);
            System.IO.FileInfo[] files = dirInfo.GetFiles("*");//all files
            foreach (FileInfo file in files)
            {
                if (IsStrip != null && IsStrip(file.FullName))
                    continue;//skip, don't zip it
                java.io.FileInputStream instream = new java.io.FileInputStream(file.FullName);
                int bytes = 0;
                string strEntry = file.FullName.Substring(m_trimIndex);
                _zos.putNextEntry(new ZipEntry(strEntry));
                while ((bytes = instream.read(_buffer, 0, _buffer.Length)) > 0)
                {
                    _zos.write(_buffer, 0, bytes);
                }
                _zos.closeEntry();
                instream.close();
                System.Windows.Forms.Application.DoEvents();
            }

            System.IO.DirectoryInfo[] folders = null;
            folders = dirInfo.GetDirectories("*");
            if (folders != null)
            {
                foreach (System.IO.DirectoryInfo folder in folders)
                {
                    _CreateZipFromFolder(folder.FullName, IsStrip);
                }
            }

        }

        public static void StripZip(string zipFile, List<string> trashFiles)
        {
            if (zipFile == null ||zipFile.Length == 0 || !File.Exists(zipFile))
            return;
            ZipOutputStream zos = null;
            ZipInputStream zis = null;
            //remove 'zip' extension
            bool bsuccess = true;
            string strNewFile = zipFile.Remove(zipFile.Length - 3, 3) + "tmp";
            try
            {
                zos = new ZipOutputStream(new java.io.FileOutputStream(strNewFile));
                zis = new ZipInputStream(new java.io.FileInputStream(zipFile));
                ZipEntry ze = null;
                while ((ze = zis.getNextEntry()) != null)
                {
                    if (ze.isDirectory())
                        continue;//ignore directories
                    string fname = ze.getName();
                    bool bstrip = trashFiles.Contains(fname);

                    if (!bstrip)
                    {
                        //copy the entry from zis to zos
                        int bytes = 0;
                        try
                        {
                            //deal with password protected files
                            zos.putNextEntry(new ZipEntry(fname));
                            while ((bytes = zis.read(_buffer, 0, _buffer.Length)) > 0)
                            {
                                zos.write(_buffer, 0, bytes);
                                System.Windows.Forms.Application.DoEvents();
                            }
                        }
                        catch (Exception)
                        {
                            bsuccess = false;
                            throw;
                        }
                        finally
                        {
                            zis.closeEntry();
                            zos.closeEntry();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                bsuccess = false;
                throw new ApplicationException("unable to zip/unzip: " + zipFile, ex);
            }
            finally
            {
                if (zis != null)
                    zis.close();
                if (zos != null)
                    zos.close();
                if (bsuccess)
                {
                    System.IO.File.Delete(zipFile + ".old");
                    System.IO.File.Move(zipFile, zipFile + ".old");
                    System.IO.File.Move(strNewFile, zipFile);
                }
                else
                {
                    System.IO.File.Delete(strNewFile);
                }
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes")]
        public static void UnZip(string file, string Folder, IsFileStrippableDelegate IsStrip)
        {
            if (file == null || file.Length == 0 || !File.Exists(file))
                return;

            ZipInputStream zis = null;
            try
            {
                zis = new ZipInputStream(new java.io.FileInputStream(file));
                ZipEntry ze = null;
                while ((ze = zis.getNextEntry()) != null)
                {
                    if (ze.isDirectory())
                        continue;//ignore directories
                    string fname = ze.getName();
                    bool bstrip = IsStrip != null && IsStrip(fname);

                    if (!bstrip)
                    {
                        //unzip entry
                        int bytes = 0;
                        FileStream filestream = null;
                        BinaryWriter w = null;
                        try
                        {
                            string filePath = Folder + @"\" + fname;
                            if(!Directory.Exists(Path.GetDirectoryName(filePath)))
                                Directory.CreateDirectory(Path.GetDirectoryName(filePath));
                            filestream = new FileStream(filePath, FileMode.Create);
                            w = new BinaryWriter(filestream);
                            
                            while ((bytes = zis.read(_buffer, 0, _buffer.Length)) > 0)
                            {
                                System.Windows.Forms.Application.DoEvents();
                                for (int i = 0; i < bytes; i++)
			                    {
                                    unchecked
                                    {
                                        w.Write((byte)_buffer[i]);
                                    }
			                    }
                            }
                        }
                        catch (Exception)
                        {
                            throw;
                        }
                        finally
                        {
                            zis.closeEntry();
                            w.Close();
                            filestream.Close();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new ApplicationException("unable to unzip: " + file +"\nIt might be password protected.", ex);
            }
            finally
            {
                if (zis != null)
                    zis.close();
            }

        }

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
Decebal Mihailescu is a software engineer with interest in .Net, C# and C++.

Comments and Discussions