zoukankan      html  css  js  c++  java
  • C#- 压缩和解压缩的研究 .

    用了第二种方法,感觉很不错,其他都没用过了。摘录下来,做一个备忘。

    最近在网上查了一下在.net中进行压缩和解压缩的方法,方法有很多,我找到了以下几种:

    1.利用.net自带的压缩和解压缩方法GZip

    参考代码如下:

    //========================================================================
        //  类名: CommonCompress
        /// <summary>
        /// 用于对文件和字符串进行压缩
        /// </summary>
        /// <remarks>
        /// 用于对文件和字符串进行压缩
        /// </remarks>
        /*=======================================================================
        变更记录
        序号   更新日期  开发者   变更内容
        0001   2008/07/22  张          新建
        =======================================================================*/
        public class CommonCompress
        {
            /// <summary>
            /// 压缩字符串
            /// </summary>
            /// <param name="strUncompressed">未压缩的字符串</param>
            /// <returns>压缩的字符串</returns>
            public static string StringCompress(string strUncompressed)
            {
                byte[] bytData = System.Text.Encoding.Unicode.GetBytes(strUncompressed);
                MemoryStream ms = new MemoryStream();
                Stream s = new GZipStream(ms, CompressionMode.Compress);
                s.Write(bytData, 0, bytData.Length);
                s.Close();
                byte[] dataCompressed = (byte[])ms.ToArray();
                return System.Convert.ToBase64String(dataCompressed, 0, dataCompressed.Length);
            }
    
            /// <summary>
            /// 解压缩字符串
            /// </summary>
            /// <param name="strCompressed">压缩的字符串</param>
            /// <returns>未压缩的字符串</returns>
            public static string StringDeCompress(string strCompressed)
            {
                System.Text.StringBuilder strUncompressed = new System.Text.StringBuilder();
                int totalLength = 0;
                byte[] bInput = System.Convert.FromBase64String(strCompressed); ;
                byte[] dataWrite = new byte[4096];
                Stream s = new GZipStream(new MemoryStream(bInput), CompressionMode.Decompress);
                while (true)
                {
                    int size = s.Read(dataWrite, 0, dataWrite.Length);
                    if (size > 0)
                    {
                        totalLength += size;
                        strUncompressed.Append(System.Text.Encoding.Unicode.GetString(dataWrite, 0, size));
                    }
                    else
                    {
                        break;
                    }
                }
                s.Close();
                return strUncompressed.ToString();
            }
    
            /// <summary>
            /// 压缩文件
            /// </summary>
            /// <param name="iFile">压缩前文件路径</param>
            /// <param name="oFile">压缩后文件路径</param>
            public static void CompressFile(string iFile, string oFile)
            {
                //判断文件是否存在
                if (File.Exists(iFile) == false)
                {
                    throw new FileNotFoundException("文件未找到!");
                }
                //创建文件流
                byte[] buffer = null;
                FileStream iStream = null;
                FileStream oStream = null;
                GZipStream cStream = null;
                try
                {
                    //把文件写进数组
                    iStream = new FileStream(iFile, FileMode.Open, FileAccess.Read, FileShare.Read);
                    buffer = new byte[iStream.Length];
                    int num = iStream.Read(buffer, 0, buffer.Length);
                    if (num != buffer.Length)
                    {
                        throw new ApplicationException("压缩文件异常!");
                    }
                    //创建文件输出流并输出
                    oStream = new FileStream(oFile, FileMode.OpenOrCreate, FileAccess.Write);
                    cStream = new GZipStream(oStream, CompressionMode.Compress, true);
                    cStream.Write(buffer, 0, buffer.Length);
                }
                finally
                {
                    //关闭流对象
                    if (iStream != null) iStream.Close();
                    if (cStream != null) cStream.Close();
                    if (oStream != null) oStream.Close();
                }
            }
    
            /// <summary>
            /// 解压缩文件
            /// </summary>
            /// <param name="iFile">压缩前文件路径</param>
            /// <param name="oFile">压缩后文件路径</param>
            public static void DecompressFile(string iFile, string oFile)
            {
                //判断文件是否存在
                if (File.Exists(iFile) == false)
                {
                    throw new FileNotFoundException("文件未找到!");
                }
                //创建文件流
                FileStream iStream = null;
                FileStream oStream = null;
                GZipStream dStream = null;
                byte[] qBuffer = new byte[4];
                try
                {
                    //把压缩文件写入数组
                    iStream = new FileStream(iFile, FileMode.Open);
                    dStream = new GZipStream(iStream, CompressionMode.Decompress, true);
                    int position = (int)iStream.Length - 4;
                    iStream.Position = position;
                    iStream.Read(qBuffer, 0, 4);
                    iStream.Position = 0;
                    int num = BitConverter.ToInt32(qBuffer, 0);
                    byte[] buffer = new byte[num + 100];
                    int offset = 0, total = 0;
                    while (true)
                    {
                        int bytesRead = dStream.Read(buffer, offset, 100);
                        if (bytesRead == 0) break;
                        offset += bytesRead;
                        total += bytesRead;
                    }
                    //创建输出流并输出
                    oStream = new FileStream(oFile, FileMode.Create);
                    oStream.Write(buffer, 0, total);
                    oStream.Flush();
                }
                finally
                {
                    //关闭流对象
                    if (iStream != null) iStream.Close();
                    if (dStream != null) dStream.Close();
                    if (oStream != null) oStream.Close();
                }
            }
        }

    2.利用ICSharpCode的压缩和解压缩方法,需引用ICSharpCode.SharpZipLib.dll,这个类库是开源的,源码地址http://www.icsharpcode.net/OpenSource/SharpZipLib/Download.aspx

    参考代码如下:

    using System;
    using System.Collections.Generic; 
    using System.IO;
    
    using ICSharpCode.SharpZipLib.Zip;
    using ICSharpCode.SharpZipLib.Checksums;
    
    namespace ZYBNET.FW.Utility.CommonMethod
    {
        //========================================================================
        //  类名: ZipHelper
        /// <summary>
        /// 用于对文件和字符串进行压缩
        /// </summary>
        /// <remarks>
        /// 用于对文件和字符串进行压缩
        /// </remarks>
        /*=======================================================================
        变更记录
        序号   更新日期  开发者   变更内容
        0001   2008/07/22  张          新建
        =======================================================================*/
        public class ZipHelper
        {
            #region 压缩文件夹,支持递归
            /// <summary>
            /// 压缩文件夹
            /// </summary>
            /// <param name="dir">待压缩的文件夹</param>
            /// <param name="targetFileName">压缩后文件路径(包括文件名)</param>
            /// <param name="recursive">是否递归压缩</param>
            /// <returns></returns>
            public static bool Compress(string dir, string targetFileName, bool recursive)
            {
                //如果已经存在目标文件,询问用户是否覆盖
                if (File.Exists(targetFileName))
                {
                    throw new Exception("同名文件已经存在!");
                }
                string[] ars = new string[2];
                if (recursive == false)
                {
                    ars[0] = dir;
                    ars[1] = targetFileName;
                    return ZipFileDictory(ars);
                }
    
                FileStream zipFile;
                ZipOutputStream zipStream;
    
                //打开压缩文件流
                zipFile = File.Create(targetFileName);
                zipStream = new ZipOutputStream(zipFile);
    
                if (dir != String.Empty)
                {
                    CompressFolder(dir, zipStream, dir);
                }
    
                //关闭压缩文件流
                zipStream.Finish();
                zipStream.Close();
    
                if (File.Exists(targetFileName))
                    return true;
                else
                    return false;
            }
    
            /// <summary>
            /// 压缩目录
            /// </summary>
            /// <param name="args">数组(数组[0]: 要压缩的目录; 数组[1]: 压缩的文件名)</param>
            public static bool ZipFileDictory(string[] args)
            {
                ZipOutputStream zStream = null;
                try
                {
                    string[] filenames = Directory.GetFiles(args[0]);
                    Crc32 crc = new Crc32();
                    zStream = new ZipOutputStream(File.Create(args[1]));
                    zStream.SetLevel(6);
                    //循环压缩文件夹中的文件
                    foreach (string file in filenames)
                    {
                        //打开压缩文件
                        FileStream fs = File.OpenRead(file);
                        byte[] buffer = new byte[fs.Length];
                        fs.Read(buffer, 0, buffer.Length);
                        ZipEntry entry = new ZipEntry(file);
                        entry.DateTime = DateTime.Now;
                        entry.Size = fs.Length;
                        fs.Close();
                        crc.Reset();
                        crc.Update(buffer);
                        entry.Crc = crc.Value;
                        zStream.PutNextEntry(entry);
                        zStream.Write(buffer, 0, buffer.Length);
                    }
                }
                catch
                {
                    throw;
                }
                finally
                {
                    zStream.Finish();
                    zStream.Close();
                }
                return true;
            }
    
            /// <summary>
            /// 压缩某个子文件夹
            /// </summary>
            /// <param name="basePath">待压缩路径</param>
            /// <param name="zips">压缩文件流</param>
            /// <param name="zipfolername">待压缩根路径</param>     
            private static void CompressFolder(string basePath, ZipOutputStream zips, string zipfolername)
            {
                if (File.Exists(basePath))
                {
                    AddFile(basePath, zips, zipfolername);
                    return;
                }
                string[] names = Directory.GetFiles(basePath);
                foreach (string fileName in names)
                {
                    AddFile(fileName, zips, zipfolername);
                }
    
                names = Directory.GetDirectories(basePath);
                foreach (string folderName in names)
                {
                    CompressFolder(folderName, zips, zipfolername);
                }
    
            }
    
            /// <summary>
            /// 压缩某个子文件
            /// </summary>
            /// <param name="fileName">待压缩文件</param>
            /// <param name="zips">压缩流</param>
            /// <param name="zipfolername">待压缩根路径</param>
            private static void AddFile(string fileName, ZipOutputStream zips, string zipfolername)
            {
                if (File.Exists(fileName))
                {
                    CreateZipFile(fileName, zips, zipfolername);
                }
            }
    
            /// <summary>
            /// 压缩单独文件
            /// </summary>
            /// <param name="FileToZip">待压缩文件</param>
            /// <param name="zips">压缩流</param>
            /// <param name="zipfolername">待压缩根路径</param>
            private static void CreateZipFile(string FileToZip, ZipOutputStream zips, string zipfolername)
            {
                try
                {
                    FileStream StreamToZip = new FileStream(FileToZip, FileMode.Open, FileAccess.Read);
                    string temp = FileToZip;
                    string temp1 = zipfolername;
                    if (temp1.Length > 0)
                    {
                        temp = temp.Replace(zipfolername + "\", "");
                    }
                    ZipEntry ZipEn = new ZipEntry(temp);
    
                    zips.PutNextEntry(ZipEn);
                    byte[] buffer = new byte[16384];
                    System.Int32 size = StreamToZip.Read(buffer, 0, buffer.Length);
                    zips.Write(buffer, 0, size);
                    try
                    {
                        while (size < StreamToZip.Length)
                        {
                            int sizeRead = StreamToZip.Read(buffer, 0, buffer.Length);
                            zips.Write(buffer, 0, sizeRead);
                            size += sizeRead;
                        }
                    }
                    catch (System.Exception ex)
                    {
                        throw ex;
                    }
    
                    StreamToZip.Close();
                }
                catch
                {
                    throw;
                }
            }
            #endregion
    
            #region 解压缩
            /// <summary>   
            /// 功能:解压zip格式的文件。   
            /// </summary>   
            /// <param name="zipFilePath">压缩文件路径</param>   
            /// <param name="unZipDir">解压文件存放路径,为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹</param>   
            /// <returns>解压是否成功</returns>   
            public static void UnZipFile(string zipFilePath, string unZipDir)
            {
     
                if (zipFilePath == string.Empty)
                {
                    throw new Exception("压缩文件不能为空!");
                }
                if (!File.Exists(zipFilePath))
                {
                    throw new Exception("压缩文件不存在!");
                }
                //解压文件夹为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹   
                if (unZipDir == string.Empty)
                    unZipDir = zipFilePath.Replace(Path.GetFileName(zipFilePath), Path.GetFileNameWithoutExtension(zipFilePath));
                if (!unZipDir.EndsWith("//"))
                    unZipDir += "//";
                if (!Directory.Exists(unZipDir))
                    Directory.CreateDirectory(unZipDir);
    
                try
                {
                    using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipFilePath)))
                    {
                        ZipEntry theEntry;
                        while ((theEntry = s.GetNextEntry()) != null)
                        {
                            string directoryName = Path.GetDirectoryName(theEntry.Name);
                            string fileName = Path.GetFileName(theEntry.Name);
                            if (directoryName.Length > 0)
                            {
                                Directory.CreateDirectory(unZipDir + directoryName);
                            }
                            if (!directoryName.EndsWith("//"))
                                directoryName += "//";
                            if (fileName != String.Empty)
                            {
                                using (FileStream streamWriter = File.Create(unZipDir + theEntry.Name))
                                {
                                    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;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                catch 
                {
                    throw;
                }
            }
            #endregion
    
        }
    }

    3.利用java的压缩和解压缩方法,需引用vjslib.dll

    至于这种方法的使用,大家可以去查阅msdn,这里就不写了

    4.利用zlibwapi.dll的API进行压缩

    据说压缩效率比较好,但是在网上没找到供下载的链接,有兴趣的朋友可以试试

    5.使用System.IO.Packaging压缩和解压

    System.IO.Packaging在WindowsBase.dll程序集下,使用时需要添加对WindowsBase的引用

    /// <summary>
            /// Add a folder along with its subfolders to a Package
            /// </summary>
            /// <param name="folderName">The folder to add</param>
            /// <param name="compressedFileName">The package to create</param>
            /// <param name="overrideExisting">Override exsisitng files</param>
            /// <returns></returns>
            static bool PackageFolder(string folderName, string compressedFileName, bool overrideExisting)
            {
                if (folderName.EndsWith(@""))
                    folderName = folderName.Remove(folderName.Length - 1);
                bool result = false;
                if (!Directory.Exists(folderName))
                {
                    return result;
                }
    
                if (!overrideExisting && File.Exists(compressedFileName))
                {
                    return result;
                }
                try
                {
                    using (Package package = Package.Open(compressedFileName, FileMode.Create))
                    {
                        var fileList = Directory.EnumerateFiles(folderName, "*", SearchOption.AllDirectories);
                        foreach (string fileName in fileList)
                        {
                           
                            //The path in the package is all of the subfolders after folderName
                            string pathInPackage;
                            pathInPackage = Path.GetDirectoryName(fileName).Replace(folderName, string.Empty) + "/" + Path.GetFileName(fileName);
    
                            Uri partUriDocument = PackUriHelper.CreatePartUri(new Uri(pathInPackage, UriKind.Relative));
                            PackagePart packagePartDocument = package.CreatePart(partUriDocument,"", CompressionOption.Maximum);
                            using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
                            {
                                fileStream.CopyTo(packagePartDocument.GetStream());
                            }
                        }
                    }
                    result = true;
                }
                catch (Exception e)
                {
                    throw new Exception("Error zipping folder " + folderName, e);
                }
               
                return result;
            }
    
    
     /// <summary>
            /// Compress a file into a ZIP archive as the container store
            /// </summary>
            /// <param name="fileName">The file to compress</param>
            /// <param name="compressedFileName">The archive file</param>
            /// <param name="overrideExisting">override existing file</param>
            /// <returns></returns>
            static bool PackageFile(string fileName, string compressedFileName, bool overrideExisting)
            {
                bool result = false;
    
                if (!File.Exists(fileName))
                {
                    return result;
                }
    
                if (!overrideExisting && File.Exists(compressedFileName))
                {
                    return result;
                }
    
                try
                {
                    Uri partUriDocument = PackUriHelper.CreatePartUri(new Uri(Path.GetFileName(fileName), UriKind.Relative));
                   
                    using (Package package = Package.Open(compressedFileName, FileMode.OpenOrCreate))
                    {
                        if (package.PartExists(partUriDocument))
                        {
                            package.DeletePart(partUriDocument);
                        } 
    
                        PackagePart packagePartDocument = package.CreatePart(partUriDocument, "", CompressionOption.Maximum);
                        using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
                        {
                            fileStream.CopyTo(packagePartDocument.GetStream());
                        }
                    }
                    result = true;
                }
                catch (Exception e)
                {
                    throw new Exception("Error zipping file " + fileName, e);
                }
                
                return result;
            }
    
    
    }       3、zip文件解压
    
    Code/// <summary>
            /// Extract a container Zip. NOTE: container must be created as Open Packaging Conventions (OPC) specification
            /// </summary>
            /// <param name="folderName">The folder to extract the package to</param>
            /// <param name="compressedFileName">The package file</param>
            /// <param name="overrideExisting">override existing files</param>
            /// <returns></returns>
            static bool UncompressFile(string folderName, string compressedFileName, bool overrideExisting)
            {
                bool result = false;
                try
                {
                    if (!File.Exists(compressedFileName))
                    {
                        return result;
                    }
    
                    DirectoryInfo directoryInfo = new DirectoryInfo(folderName);
                    if (!directoryInfo.Exists)
                        directoryInfo.Create();
    
                    using (Package package = Package.Open(compressedFileName, FileMode.Open, FileAccess.Read))
                    {
                        foreach (PackagePart packagePart in package.GetParts())
                        {
                            ExtractPart(packagePart, folderName, overrideExisting);
                        }
                    }
    
                    result = true;
                }
                catch (Exception e)
                {
                    throw new Exception("Error unzipping file " + compressedFileName, e);
                }
                
                return result;
            }
    
            static void ExtractPart(PackagePart packagePart, string targetDirectory, bool overrideExisting)
            {
                string stringPart = targetDirectory + HttpUtility.UrlDecode(packagePart.Uri.ToString()).Replace('\', '/');
    
                if (!Directory.Exists(Path.GetDirectoryName(stringPart)))
                    Directory.CreateDirectory(Path.GetDirectoryName(stringPart));
    
                if (!overrideExisting && File.Exists(stringPart))
                    return;
                using (FileStream fileStream = new FileStream(stringPart, FileMode.Create))
                {
                    packagePart.GetStream().CopyTo(fileStream);
                }
            }


    原文网址:http://blog.csdn.net/fhzh520/article/details/1491900

  • 相关阅读:
    .net core + mvc 手撸一个代码生成器
    如何使用VS Code编写Spring Boot (第二弹)
    第五章 .net core该怎么玩
    第四章 .net core做一个简单的登录
    第三章 搭建一个通用的权限管理系统
    第二章 在Linux上部署.net core
    将博客搬至CSDN
    Entity Framework6 with Oracle(可实现code first)
    利用windbg查找dictionary导致IIS占CPU100%案例分析(一)
    VS快捷键以及Reshaper快捷键
  • 原文地址:https://www.cnblogs.com/cxeye/p/3602498.html
Copyright © 2011-2022 走看看