使用ICSharpCode.SharpZipLib.Zip实现压缩与解压缩

使用开源类库ICSharpCode.SharpZipLib.Zip可以实现压缩与解压缩功能,源代码和DLL可以从http://www.icsharpcode.net/OpenSource/SharpZipLib/Default.aspx下载;

 

有两种方式可以实现压缩与解压缩,这里只提供了ZIP格式;

1、DLL本身提供的快速压缩与解压缩,直接代码:

using System;
using ICSharpCode.SharpZipLib.Zip;

namespace Zip
{
    public static class FastZipHelper
    {
        #region CreateZipFile

        public static bool CreateZip(string zipFileName, string sourceDirectory, bool recurse, string fileFilter,
                                     string directoryFilter, bool createEmptyDirectories,
                                     bool restoreAttributesOnExtract, bool restoreDateTimeOnExtract)
        {
            try
            {
                FastZip fastZip = new FastZip();
                fastZip.CreateEmptyDirectories = createEmptyDirectories;
                fastZip.RestoreAttributesOnExtract = restoreAttributesOnExtract;
                fastZip.RestoreDateTimeOnExtract = restoreDateTimeOnExtract;
                fastZip.CreateZip(zipFileName, sourceDirectory, recurse, fileFilter, directoryFilter);
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        public static bool CreateZip(string zipFileName, string sourceDirectory, bool recurse, string fileFilter,
                                     string directoryFilter, bool createEmptyDirectories)
        {
            return CreateZip(zipFileName, sourceDirectory, recurse, fileFilter, directoryFilter, createEmptyDirectories,
                             true, true);
        }

        public static bool CreateZip(string zipFileName, string sourceDirectory, bool recurse, string fileFilter,
                                     string directoryFilter)
        {
            return CreateZip(zipFileName, sourceDirectory, recurse, fileFilter, directoryFilter, true);
        }

        public static bool CreateZip(string zipFileName, string sourceDirectory, bool recurse, string fileFilter)
        {
            return CreateZip(zipFileName, sourceDirectory, recurse, fileFilter, string.Empty);
        }

        public static bool CreateZip(string zipFileName, string sourceDirectory, bool recurse)
        {
            return CreateZip(zipFileName, sourceDirectory, recurse, string.Empty);
        }

        public static bool CreateZip(string zipFileName, string sourceDirectory)
        {
            return CreateZip(zipFileName, sourceDirectory, true);
        }

        #endregion

        #region ExtractZip

        public static bool ExtractZip(string zipFileName, string targetDirectory, FastZip.Overwrite overwrite,
                                      FastZip.ConfirmOverwriteDelegate confirmDelegate, string fileFilter,
                                      string directoryFilter, bool restoreDateTime, bool createEmptyDirectories,
                                      bool restoreAttributesOnExtract, bool restoreDateTimeOnExtract)
        {
            try
            {
                FastZip fastZip = new FastZip();
                fastZip.CreateEmptyDirectories = createEmptyDirectories;
                fastZip.RestoreAttributesOnExtract = restoreAttributesOnExtract;
                fastZip.RestoreDateTimeOnExtract = restoreDateTimeOnExtract;
                fastZip.ExtractZip(zipFileName, targetDirectory, overwrite, confirmDelegate, fileFilter, directoryFilter,
                                   restoreDateTime);
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        public static bool ExtractZip(string zipFileName, string targetDirectory, FastZip.Overwrite overwrite,
                                      FastZip.ConfirmOverwriteDelegate confirmDelegate, string fileFilter,
                                      string directoryFilter, bool restoreDateTime, bool createEmptyDirectories)
        {
            return ExtractZip(zipFileName, targetDirectory, overwrite, confirmDelegate, fileFilter, directoryFilter,
                              restoreDateTime, createEmptyDirectories, true, true);
        }

        public static bool ExtractZip(string zipFileName, string targetDirectory, FastZip.Overwrite overwrite,
                                      FastZip.ConfirmOverwriteDelegate confirmDelegate, string fileFilter,
                                      string directoryFilter, bool restoreDateTime)
        {
            return ExtractZip(zipFileName, targetDirectory, overwrite, confirmDelegate, fileFilter, directoryFilter,
                              restoreDateTime, true);
        }

        public static bool ExtractZip(string zipFileName, string targetDirectory, FastZip.Overwrite overwrite,
                                      FastZip.ConfirmOverwriteDelegate confirmDelegate, string fileFilter,
                                      string directoryFilter)
        {
            return ExtractZip(zipFileName, targetDirectory, overwrite, confirmDelegate, fileFilter, directoryFilter,
                              true);
        }

        public static bool ExtractZip(string zipFileName, string targetDirectory, FastZip.Overwrite overwrite,
                                      FastZip.ConfirmOverwriteDelegate confirmDelegate, string fileFilter)
        {
            return ExtractZip(zipFileName, targetDirectory, overwrite, confirmDelegate, fileFilter, string.Empty);
        }

        public static bool ExtractZip(string zipFileName, string targetDirectory)
        {
            return ExtractZip(zipFileName, targetDirectory, string.Empty);
        }

        public static bool ExtractZip(string zipFileName, string targetDirectory, string fileFilter)
        {
            return ExtractZip(zipFileName, targetDirectory, FastZip.Overwrite.Always, null, fileFilter);
        }

        #endregion
    }
}

  

2、自己实现:

using System;
using System.Collections.Generic;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;

namespace Zip
{
    public static class ZipHelper
    {
        public static string[] GetDirectories(string sourceDirectory)
        {
            List<string> result = new List<string>();

            string[] directories = Directory.GetDirectories(sourceDirectory);
            if (directories.Length > 0)
            {
                foreach (var directory in directories)
                {
                    result.Add(directory);
                    result.AddRange(GetDirectories(directory));
                }
            }
            return result.ToArray();
        }

        public static string[] GetFiles(string sourceDirectory)
        {
            List<string> result = new List<string>();
            result.AddRange(Directory.GetFiles(sourceDirectory));
            string[] directories = Directory.GetDirectories(sourceDirectory);
            if (directories.Length > 0)
            {
                foreach (var directory in directories)
                {
                    result.AddRange(GetFiles(directory));
                }
            }
            return result.ToArray();
        }

        #region CreateZipFile

        public static void CreateZip(string sourceDirectory)
        {
            CreateZip(sourceDirectory, null);
        }

        public static void CreateZip(string sourceDirectory, string zipFileName)
        {
            if (string.IsNullOrEmpty(sourceDirectory))
            {
                throw new ArgumentNullException("sourceDirectory", "sourceDirectory can not be null or empty.");
            }
            if (!Directory.Exists(sourceDirectory))
            {
                throw new DirectoryNotFoundException(sourceDirectory + " can not be found.");
            }
            if (string.IsNullOrEmpty(zipFileName))
            {
                zipFileName = sourceDirectory.TrimEnd('\\').TrimEnd('/') + ".zip";
            }
            // Depending on the directory this could be very large and would require more attention
            // in a commercial package.
            //string[] filenames = Directory.GetFiles(sourceDirectory);
            string[] directories = GetDirectories(sourceDirectory);
            string[] filenames = GetFiles(sourceDirectory);
            if (!Directory.Exists(Path.GetDirectoryName(zipFileName)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(zipFileName));
            }
            // 'using' statements guarantee the stream is closed properly which is a big source
            // of problems otherwise.  Its exception safe as well which is great.
            using (ZipOutputStream s = new ZipOutputStream(File.Create(zipFileName)))
            {
                s.SetLevel(9); // 0 - store only to 9 - means best compression

                ZipEntryFactory factory = new ZipEntryFactory();
                foreach (var directory in directories)
                {
                    string virtualDirectory = directory.Replace(sourceDirectory, string.Empty);
                    ZipEntry zipEntry = factory.MakeDirectoryEntry(virtualDirectory);
                    zipEntry.DateTime = DateTime.Now;
                    s.PutNextEntry(zipEntry);
                }

                byte[] buffer = new byte[4096];

                foreach (string file in filenames)
                {
                    // Using GetFileName makes the result compatible with XP
                    // as the resulting path is not absolute.
                    string newfileName = file.Replace(sourceDirectory, string.Empty);
                    ZipEntry entry = factory.MakeFileEntry(newfileName);

                    // Setup the entry data as required.

                    // Crc and size are handled by the library for seakable streams
                    // so no need to do them here.

                    // Could also use the last write time or similar for the file.
                    entry.DateTime = DateTime.Now;
                    s.PutNextEntry(entry);

                    using (FileStream fs = File.OpenRead(file))
                    {
                        // Using a fixed size buffer here makes no noticeable difference for output
                        // but keeps a lid on memory usage.
                        int sourceBytes;
                        do
                        {
                            sourceBytes = fs.Read(buffer, 0, buffer.Length);
                            s.Write(buffer, 0, sourceBytes);
                        } while (sourceBytes > 0);
                    }
                }

                // Finish/Close arent needed strictly as the using statement does this automatically

                // Finish is important to ensure trailing information for a Zip file is appended.  Without this
                // the created file would be invalid.
                s.Finish();

                // Close is important to wrap things up and unlock the file.
                s.Close();
            }
        }

        #endregion

        #region ExtractZip

        public static void ExtractZip(string zipFileName)
        {
            ExtractZip(zipFileName, null);
        }

        public static void ExtractZip(string zipFileName, string targetDirectory)
        {
            if (string.IsNullOrEmpty(zipFileName))
            {
                throw new ArgumentNullException("zipFileName", "zipFileName can not be null or empty.");
            }

            if (!File.Exists(zipFileName))
            {
                throw new FileNotFoundException(zipFileName + " can not be found.");
            }

            if (string.IsNullOrEmpty(targetDirectory))
            {
                targetDirectory = Path.Combine(Path.GetDirectoryName(zipFileName),
                                               Path.GetFileNameWithoutExtension(zipFileName));
            }
            using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipFileName)))
            {
                ZipEntry theEntry;
                while ((theEntry = s.GetNextEntry()) != null)
                {
                    //create directory
                    string targetPath = Path.Combine(targetDirectory, theEntry.Name);
                    if (theEntry.IsDirectory)
                    {
                        Directory.CreateDirectory(targetPath);
                    }
                    if (theEntry.IsFile)
                    {
                        if (!Directory.Exists(Path.GetDirectoryName(targetPath)))
                        {
                            Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
                        }
                        using (FileStream streamWriter = File.Create(targetPath))
                        {
                            int size = 2048;
                            byte[] data = new byte[2048];
                            while (true)
                            {
                                size = s.Read(data, 0, data.Length);
                                if (size > 0)
                                {
                                    streamWriter.Write(data, 0, size);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }

        #endregion
    }
}

  

 

posted @ 2013-10-15 10:21  xiaotou745  阅读(1132)  评论(0编辑  收藏  举报