经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C# » 查看文章
C#使用第三方SharpZipLib进行压缩、解压文件
来源:cnblogs  作者:Harley520  时间:2018/10/15 9:30:49  对本文有异议

近在做项目时用到了文件的批量压缩下载,使用了第三方的SharpZipLib包,后来想到了单个文件的压缩与解压,可能以后会用到相关技术,所以自己熟悉了一下并且借鉴了一些网上的相关代码,自己整理一下,这里我用到的是SharpZipLib 1.0.0版本,这里我新建一个控制台项目来展示。

 

一:创建项目并安装所需DLL

1、新建控制台项目ConsoleCompressApp

2、通过VisualStudio菜单中工具->NuGet包管理器->程序包管理控制台安装SharpZipLib包

命令是Install-Package SharpZipLib,如下图显示,已安装完成。

也可以通过鼠标选中项目然后右键弹出的菜单中选择管理NuGet程序包

选择第一个SharpZipLib包选择安装即可。

 

二:创建日志记录帮助类LogHelper

  1.  1 using System; 2 using System.IO; 3  4 namespace ConsoleCompressApp 5 { 6     public class LogHelper 7     { 8         private static readonly object __lockObject = new object(); 9         public static void Write(string message, string txtFileName = "")10         {11             try12             {13                 if (string.IsNullOrWhiteSpace(txtFileName))14                 {15                     txtFileName = AppDomain.CurrentDomain.BaseDirectory + Path.DirectorySeparatorChar + "log.txt";16                 }17                 FileStream fs = null;18                 if (File.Exists(txtFileName))19                 {20                     fs = new FileStream(txtFileName, FileMode.Append);21                 }22                 else23                 {24                     fs = new FileStream(txtFileName, FileMode.Create);25                 }26                 lock (__lockObject)27                 {28                     if (File.Exists(txtFileName) == false)29                     {30                         File.Create(txtFileName);31                     }32                     using (StreamWriter sw = new StreamWriter(fs))33                     {34                         sw.Write("{0}:{1}", DateTime.Now.ToString("yyyy年MM月dd日 HH:mm:ss"), message + sw.NewLine);35                     }36                 }37 38             }39             catch (Exception)40             {41                 throw;42             }43         }44     }45 }

 

三:创建压缩文件的帮助类SharpZipLibHelper

1、新建SharpZipLibHelper帮助类,并引用如下命名空间

  1.  1 using System; 2 using System.IO; 3 using ICSharpCode.SharpZipLib.Checksum; 4 using ICSharpCode.SharpZipLib.Zip; 5  6 namespace ConsoleCompressApp 7 { 8     public class SharpZipLibHelper 9     {10 11     }12 }

2、添加压缩单个文件的静态方法

  1.  1         /// <summary> 2         /// 单个文件进行压缩 3         /// </summary> 4         /// <param name="fileName">待压缩的文件(绝对路径)</param> 5         /// <param name="compressedFilePath">压缩后文件路径(绝对路径)</param> 6         /// <param name="aliasFileName">压缩文件的名称(别名)</param> 7         /// <param name="compressionLevel">压缩级别0-9,默认为5</param> 8         /// <param name="blockSize">缓存大小,每次写入文件大小,默认为2048字节</param> 9         /// <param name="isEncrypt">是否加密,默认加密</param>10         /// <param name="encryptPassword">加密的密码(为空的时候,不加密)</param>11         public static void CompressFile(string fileName, string compressedFilePath, string aliasFileName = "", int compressionLevel = 5,12             int blockSize = 2048, bool isEncrypt = true, string encryptPassword = "")13         {14             if (File.Exists(fileName) == false) throw new FileNotFoundException("未能找到当前文件!", fileName);15             try16             {17                 string zipFileName = null;18                 ///获取待压缩文件名称(带后缀名)19                 string name = new FileInfo(fileName).Name;20                 zipFileName = compressedFilePath + Path.DirectorySeparatorChar +21                     (string.IsNullOrWhiteSpace(aliasFileName) ? name.Substring(0, name.LastIndexOf(".")) : aliasFileName) + ".zip";22                 ///使用using语句,资源使用完毕,自动释放(类需继承IDispose接口)23                 using (FileStream fs = File.Create(zipFileName))24                 {25                     using (ZipOutputStream outStream = new ZipOutputStream(fs))26                     {27                         using (FileStream inStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))28                         {29                             ///zip文档的一个条目30                             ZipEntry entry = new ZipEntry(name);31                             ///压缩加密32                             if (isEncrypt)33                             {34                                 outStream.Password = encryptPassword;35                             }36                             ///开始一个新的zip条目37                             outStream.PutNextEntry(entry);38                             ///设置压缩级别39                             outStream.SetLevel(compressionLevel);40                             ///缓冲区对象41                             byte[] buffer = new byte[blockSize];42                             ///读入缓冲区的总字节数,执行到最后读取为0时,则读取完毕43                             int sizeRead = 0;44                             do45                             {46                                 ///从流中读取字节,将该数据写入缓冲区47                                 sizeRead = inStream.Read(buffer, 0, buffer.Length);48                                 ///将给定的缓冲区的数据写入当前zip文档条目49                                 outStream.Write(buffer, 0, sizeRead);50                             }51                             while (sizeRead > 0);52                         }53                         outStream.Finish();54                     }55                 }56             }57             catch (System.Exception ex)58             {59                 LogHelper.Write(ex.ToString());60             }61         }

3、添加压缩文件目录的静态方法

  1.  1         /// <summary> 2         /// 压缩文件夹 3         /// </summary> 4         /// <param name="directory">待压缩文件夹(绝对路径)</param> 5         /// <param name="compressedDirectory">压缩后的文件夹(绝对路径)</param> 6         /// <param name="aliasFileName">压缩文件的名称(别名)</param> 7         /// <param name="isEncrypt">是否加密,默认加密</param> 8         /// <param name="encryptPassword">加密的密码(为空不进行加密)</param> 9         public static void CompressDirectory(string directory, string compressedDirectory, string aliasFileName, bool isEncrypt,10             string encryptPassword = "")11         {12             if (Directory.Exists(directory) == false) throw new DirectoryNotFoundException("未能找到当前路径!");13             try14             {15                 string zipFileName = null;16                 ///获取待压缩文件名称17                 string name = new DirectoryInfo(directory).Name;18                 zipFileName = compressedDirectory + Path.DirectorySeparatorChar +19                     (string.IsNullOrWhiteSpace(aliasFileName) ? name : aliasFileName) + ".zip";20 21                 ///使用using语句,资源使用完毕,自动释放(类需继承IDispose接口)22                 using (FileStream fs = File.Create(zipFileName))23                 {24                     using (ZipOutputStream outStream = new ZipOutputStream(fs))25                     {26                         if (isEncrypt)27                         {28                             ///压缩文件加密29                             outStream.Password = encryptPassword;30                             CompressTraversal(directory, outStream, "");31                         }32                     }33                 }34             }35             catch (System.Exception ex)36             {37                 LogHelper.Write(ex.ToString());38             }39         }40 41         /// <summary>42         /// 递归遍历目录43         /// </summary>44         private static void CompressTraversal(string directory, ZipOutputStream outStream, string parentDirectory)45         {46             ///判断路径最后一个字符是否为当前系统的DirectorySeparatorChar47             if (directory[directory.Length - 1] != Path.DirectorySeparatorChar)48             {49                 directory += Path.DirectorySeparatorChar;50             }51             Crc32 crc = new Crc32();52             var fileOrDirectory = Directory.GetFileSystemEntries(directory);53             ///遍历文件与目录54             foreach (var item in fileOrDirectory)55             {56                 ///判断是否为目录57                 if (Directory.Exists(item))58                 {59                     CompressTraversal(item, outStream, (parentDirectory + item.Substring(item.LastIndexOf(Path.DirectorySeparatorChar) + 1) + Path.DirectorySeparatorChar));60                 }61                 ///压缩文件62                 else63                 {64                     using (FileStream inStream = File.OpenRead(item))65                     {66                         ///缓存区对象67                         byte[] buffer = new byte[inStream.Length];68                         ///从文件流中读取字节,将该数据写入缓存区69                         inStream.Read(buffer, 0, buffer.Length);70                         ///获取该文件名称(附带文件目录结构,例如git\\git.exe)71                         string fileName = parentDirectory + item.Substring(item.LastIndexOf(Path.DirectorySeparatorChar) + 1);72                         ///创建zip条目73                         ZipEntry entry = new ZipEntry(fileName);74                         entry.DateTime = DateTime.Now;75                         entry.Size = inStream.Length;76 77                         crc.Reset();78                         crc.Update(buffer);79 80                         entry.Crc = crc.Value;81 82                         outStream.PutNextEntry(entry);83                         outStream.Write(buffer, 0, buffer.Length);84                     }85                 }86             }87         }

4、最后添加解压的静态方法

  1.  1         /// <summary> 2         /// 解压缩 3         /// </summary> 4         /// <param name="compressedFile">压缩文件(绝对路径)</param> 5         /// <param name="directory">目标路径(绝对路径)</param> 6         /// <param name="encryptPassword">加密密码</param> 7         /// <param name="overWrite">是否覆盖</param> 8         /// <param name="blockSize">缓存大小,每次写入文件大小,默认2048字节</param> 9         public static void UnCompressFile(string compressedFile, string directory, string encryptPassword, bool overWrite = true, int blockSize = 2048)10         {11             if (File.Exists(compressedFile) == false) throw new FileNotFoundException("未能找到压缩文件!", compressedFile);12             if (Directory.Exists(directory) == false) throw new DirectoryNotFoundException("未能找到目标路径!");13 14             ///判断路径最后一个字符是否为当前系统的DirectorySeparatorChar15             if (directory[directory.Length - 1] != Path.DirectorySeparatorChar)16             {17                 directory += Path.DirectorySeparatorChar;18             }19             try20             {21                 ///使用using语句,资源使用完毕,自动释放(类需继承IDispose接口)22                 ///打开压缩文件进行读取23                 using (FileStream fs = File.OpenRead(compressedFile))24                 {25                     ///创建压缩文件的输入流26                     using (ZipInputStream inStream = new ZipInputStream(fs))27                     {28                         ///加密的密码29                         inStream.Password = encryptPassword;30                         ZipEntry entry;31                         while ((entry = inStream.GetNextEntry()) != null)32                         {33                             ///文件的父级目录名称34                             string directoryName = null;35                             ///文件的名称,例如git\\git.exe36                             string entryName = entry.Name;37 38                             if (string.IsNullOrWhiteSpace(entryName) == false)39                             {40                                 directoryName = Path.GetDirectoryName(entryName) + Path.DirectorySeparatorChar;41                             }42                             ///获取文件名称,例如git.exe43                             string name = Path.GetFileName(entryName);44                             ///文件的父级目录的绝对路径45                             string newDirectory = directory + directoryName;46                             if (Directory.Exists(newDirectory) == false)47                             {48                                 Directory.CreateDirectory(newDirectory);49                             }50 51                             if (string.IsNullOrWhiteSpace(name) == false)52                             {53                                 ///文件的绝对路径54                                 string fileName = directory + directoryName + name;55                                 ///如果覆盖解压或者本地不存在当前文件则进行解压缩56                                 if (overWrite || File.Exists(fileName) == false)57                                 {58                                     using (FileStream fsWrite = File.Create(fileName))59                                     {60                                         ///缓存区对象61                                         byte[] buffer = new byte[blockSize];62                                         ///读取的字节数63                                         int sizeRead = 0;64                                         ///读取完成,解压完成65                                         do66                                         {67                                             ///从流中读取字节,将此数据写入缓存区68                                             sizeRead = inStream.Read(buffer, 0, buffer.Length);69                                             ///将字节写入文件流70                                             fsWrite.Write(buffer, 0, buffer.Length);71                                         } while (sizeRead > 0);72                                     }73                                 }74                             }75                         }76                     }77                 }78             }79             catch (Exception ex)80             {81                 LogHelper.Write(ex.ToString());82             }83         }

 

四:在Program类Main方法中调用方法

 1、新建几个文件目录用来测试,目录结构如下图

2、编写代码,进行压缩与解压测试,如下

  1.  1 using System; 2 using System.IO; 3  4 namespace ConsoleCompressApp 5 { 6     class Program 7     { 8         static void Main(string[] args) 9         {10             var projectDirectory = Path.GetFullPath("../..");11             var directorySeparatorChar = Path.DirectorySeparatorChar;12             Console.WriteLine("您要压缩Files\\Packages\\git.exe文件么?");13             if (Console.ReadLine().Trim().ToLower()=="yes")14             {15                 SharpZipLibHelper.CompressFile(16                  fileName: projectDirectory + directorySeparatorChar + "Files" + directorySeparatorChar +17                  "Packages" + directorySeparatorChar + "git.exe",18                  compressedFilePath: projectDirectory + directorySeparatorChar + "ZipFiles",19                  aliasFileName: "",20                  compressionLevel: 8,21                  blockSize: 2048,22                  isEncrypt: true,23                  encryptPassword: "123");24             }25             Console.WriteLine("您要压缩Files整个目录么?");26             if (Console.ReadLine().Trim().ToLower() == "yes")27             {28                 SharpZipLibHelper.CompressDirectory(29                    directory: projectDirectory + directorySeparatorChar + "Files",30                    compressedDirectory: projectDirectory + directorySeparatorChar + "ZipDirectory",31                    aliasFileName: "Files",32                    isEncrypt: true,33                    encryptPassword: "456");34             }35             Console.WriteLine("您要将ZipDirectory中的Files.zip解压缩到UnZipFiles目录中么?");36             if (Console.ReadLine().Trim().ToLower() == "yes")37             {38                 SharpZipLibHelper.UnCompressFile(compressedFile: projectDirectory + directorySeparatorChar +39                 "ZipDirectory" + directorySeparatorChar + "Files.zip",40                 directory: projectDirectory + directorySeparatorChar + "UnZipFiles",41                 encryptPassword: "456");42             }43             Console.WriteLine("恭喜您,操作完成了!");44             Console.ReadLine();45         }46     }47 }

3、点击启动,进行测试,结果如下:

文件目录如下

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号