博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#压缩库SharpZipLib的应用
阅读量:7106 次
发布时间:2019-06-28

本文共 14348 字,大约阅读时间需要 47 分钟。

   SharpZipLib是一个开源的C#压缩解压库,应用非常广泛。就像用ADO.NET操作数据库要打开连接、执行命令、关闭连接等多个步骤一样,用SharpZipLib进行压缩和解压也需要多个步骤。除了初学者会用原始的方法做一步一步完成,实际开发的时候都会进行更易用的封装。这里分享我对SharpZipLib的封装,支持对文件和字节进行压缩和解压操作,支持多个文件和文件夹压缩,支持设置备注和密码。(文章源网址:http://www.cnblogs.com/conexpress/p/SharpZipClass.html)
    SharpZipLib的官方地址是:,实际使用可以通过NuGet获取,在NuGet的地址是:
SharpZipLib_NuGet
 
在Visual Studio中可以通过NuGet程序包管理控制台输入命令PM> Install-Package SharpZipLib或者用NuGet管理界面搜索并安装。
我把使用SharpZipLib的方法卸载一个类里面,作为静态方法调用,免去创建类的麻烦。其中核心压缩和解压文件的方法代码如下:
1         ///   2         /// 压缩多个文件/文件夹  3         ///   4         /// 源文件/文件夹路径列表  5         /// 压缩文件路径  6         /// 注释信息  7         /// 压缩密码  8         /// 压缩等级,范围从0到9,可选,默认为6  9         /// 
10 public static bool CompressFile(IEnumerable
sourceList, string zipFilePath, 11 string comment = null, string password = null, int compressionLevel = 6) 12 { 13 bool result = false; 14 15 try 16 { 17 //检测目标文件所属的文件夹是否存在,如果不存在则建立 18 string zipFileDirectory = Path.GetDirectoryName(zipFilePath); 19 if (!Directory.Exists(zipFileDirectory)) 20 { 21 Directory.CreateDirectory(zipFileDirectory); 22 } 23 24 Dictionary
dictionaryList = PrepareFileSystementities(sourceList); 25 26 using (ZipOutputStream zipStream = new ZipOutputStream(File.Create(zipFilePath))) 27 { 28 zipStream.Password = password;//设置密码 29 zipStream.SetComment(comment);//添加注释 30 zipStream.SetLevel(CheckCompressionLevel(compressionLevel));//设置压缩等级 31 32 foreach (string key in dictionaryList.Keys)//从字典取文件添加到压缩文件 33 { 34 if (File.Exists(key))//判断是文件还是文件夹 35 { 36 FileInfo fileItem = new FileInfo(key); 37 38 using (FileStream readStream = fileItem.Open(FileMode.Open, 39 FileAccess.Read, FileShare.Read)) 40 { 41 ZipEntry zipEntry = new ZipEntry(dictionaryList[key]); 42 zipEntry.DateTime = fileItem.LastWriteTime; 43 zipEntry.Size = readStream.Length; 44 zipStream.PutNextEntry(zipEntry); 45 int readLength = 0; 46 byte[] buffer = new byte[BufferSize]; 47 48 do 49 { 50 readLength = readStream.Read(buffer, 0, BufferSize); 51 zipStream.Write(buffer, 0, readLength); 52 } while (readLength == BufferSize); 53 54 readStream.Close(); 55 } 56 } 57 else//对文件夹的处理 58 { 59 ZipEntry zipEntry = new ZipEntry(dictionaryList[key] + "/"); 60 zipStream.PutNextEntry(zipEntry); 61 } 62 } 63 64 zipStream.Flush(); 65 zipStream.Finish(); 66 zipStream.Close(); 67 } 68 69 result = true; 70 } 71 catch (System.Exception ex) 72 { 73 throw new Exception("压缩文件失败", ex); 74 } 75 76 return result; 77 } 78 79 ///
80 /// 解压文件到指定文件夹 81 /// 82 ///
压缩文件 83 ///
目标文件夹,如果为空则解压到当前文件夹下 84 ///
密码 85 ///
86 public static bool DecomparessFile(string sourceFile, string destinationDirectory = null, string password = null) 87 { 88 bool result = false; 89 90 if (!File.Exists(sourceFile)) 91 { 92 throw new FileNotFoundException("要解压的文件不存在", sourceFile); 93 } 94 95 if (string.IsNullOrWhiteSpace(destinationDirectory)) 96 { 97 destinationDirectory = Path.GetDirectoryName(sourceFile); 98 } 99 100 try101 {102 if (!Directory.Exists(destinationDirectory))103 {104 Directory.CreateDirectory(destinationDirectory);105 }106 107 using (ZipInputStream zipStream = new ZipInputStream(File.Open(sourceFile, FileMode.Open,108 FileAccess.Read, FileShare.Read)))109 {110 zipStream.Password = password;111 ZipEntry zipEntry = zipStream.GetNextEntry();112 113 while (zipEntry != null)114 {115 if (zipEntry.IsDirectory)//如果是文件夹则创建116 {117 Directory.CreateDirectory(Path.Combine(destinationDirectory,118 Path.GetDirectoryName(zipEntry.Name)));119 }120 else121 {122 string fileName = Path.GetFileName(zipEntry.Name);123 if (!string.IsNullOrEmpty(fileName) && fileName.Trim().Length > 0)124 {125 FileInfo fileItem = new FileInfo(Path.Combine(destinationDirectory, zipEntry.Name));126 using (FileStream writeStream = fileItem.Create())127 {128 byte[] buffer = new byte[BufferSize];129 int readLength = 0;130 131 do132 {133 readLength = zipStream.Read(buffer, 0, BufferSize);134 writeStream.Write(buffer, 0, readLength);135 } while (readLength == BufferSize);136 137 writeStream.Flush();138 writeStream.Close();139 }140 fileItem.LastWriteTime = zipEntry.DateTime;141 }142 }143 zipEntry = zipStream.GetNextEntry();//获取下一个文件144 }145 146 zipStream.Close();147 }148 result = true;149 }150 catch (System.Exception ex)151 {152 throw new Exception("文件解压发生错误", ex);153 }154 155 return result;156 }
压缩方法CompressFile中sourceList是路径数组,支持文件夹和文件的路径。当遇到文件夹时会自动将下级文件和文件夹包含,并会检测重复项。文件路径处理的方法如下:
1         ///  2         /// 为压缩准备文件系统对象 3         ///  4         ///  5         /// 
6 private static Dictionary
PrepareFileSystementities(IEnumerable
sourceFileEntityPathList) 7 { 8 Dictionary
fileEntityDictionary = new Dictionary
();//文件字典 9 string parentDirectoryPath = "";10 foreach (string fileEntityPath in sourceFileEntityPathList)11 {12 string path = fileEntityPath;13 //保证传入的文件夹也被压缩进文件14 if (path.EndsWith(@"\"))15 {16 path = path.Remove(path.LastIndexOf(@"\"));17 }18 19 parentDirectoryPath = Path.GetDirectoryName(path) + @"\";20 21 if (parentDirectoryPath.EndsWith(@":\\"))//防止根目录下把盘符压入的错误22 {23 parentDirectoryPath = parentDirectoryPath.Replace(@"\\", @"\");24 }25 26 //获取目录中所有的文件系统对象27 Dictionary
subDictionary = GetAllFileSystemEntities(path, parentDirectoryPath);28 29 //将文件系统对象添加到总的文件字典中30 foreach (string key in subDictionary.Keys)31 {32 if (!fileEntityDictionary.ContainsKey(key))//检测重复项33 {34 fileEntityDictionary.Add(key, subDictionary[key]);35 }36 }37 }38 return fileEntityDictionary;39 }40 41 ///
42 /// 获取所有文件系统对象43 /// 44 ///
源路径45 ///
顶级文件夹46 ///
字典中Key为完整路径,Value为文件(夹)名称
47 private static Dictionary
GetAllFileSystemEntities(string source, string topDirectory)48 {49 Dictionary
entitiesDictionary = new Dictionary
();50 entitiesDictionary.Add(source, source.Replace(topDirectory, ""));51 52 if (Directory.Exists(source))53 {54 //一次性获取下级所有目录,避免递归55 string[] directories = Directory.GetDirectories(source, "*.*", SearchOption.AllDirectories);56 foreach (string directory in directories)57 {58 entitiesDictionary.Add(directory, directory.Replace(topDirectory, ""));59 }60 61 string[] files = Directory.GetFiles(source, "*.*", SearchOption.AllDirectories);62 foreach (string file in files)63 {64 entitiesDictionary.Add(file, file.Replace(topDirectory, ""));65 }66 }67 68 return entitiesDictionary;69 }

除了支持文件和文件夹压缩解压,还提供了对字节的压缩解压方法:

1         ///   2         /// 压缩字节数组  3         ///   4         /// 源字节数组  5         /// 压缩等级  6         /// 密码  7         /// 
压缩后的字节数组
8 public static byte[] CompressBytes(byte[] sourceBytes, string password = null, int compressionLevel = 6) 9 { 10 byte[] result = new byte[] { }; 11 12 if (sourceBytes.Length > 0) 13 { 14 try 15 { 16 using (MemoryStream tempStream = new MemoryStream()) 17 { 18 using (MemoryStream readStream = new MemoryStream(sourceBytes)) 19 { 20 using (ZipOutputStream zipStream = new ZipOutputStream(tempStream)) 21 { 22 zipStream.Password = password;//设置密码 23 zipStream.SetLevel(CheckCompressionLevel(compressionLevel));//设置压缩等级 24 25 ZipEntry zipEntry = new ZipEntry("ZipBytes"); 26 zipEntry.DateTime = DateTime.Now; 27 zipEntry.Size = sourceBytes.Length; 28 zipStream.PutNextEntry(zipEntry); 29 int readLength = 0; 30 byte[] buffer = new byte[BufferSize]; 31 32 do 33 { 34 readLength = readStream.Read(buffer, 0, BufferSize); 35 zipStream.Write(buffer, 0, readLength); 36 } while (readLength == BufferSize); 37 38 readStream.Close(); 39 zipStream.Flush(); 40 zipStream.Finish(); 41 result = tempStream.ToArray(); 42 zipStream.Close(); 43 } 44 } 45 } 46 } 47 catch (System.Exception ex) 48 { 49 throw new Exception("压缩字节数组发生错误", ex); 50 } 51 } 52 53 return result; 54 } 55 56 /// 57 /// 解压字节数组 58 /// 59 /// 源字节数组 60 /// 密码 61 ///
解压后的字节数组
62 public static byte[] DecompressBytes(byte[] sourceBytes, string password = null) 63 { 64 byte[] result = new byte[] { }; 65 66 if (sourceBytes.Length > 0) 67 { 68 try 69 { 70 using (MemoryStream tempStream = new MemoryStream(sourceBytes)) 71 { 72 using (MemoryStream writeStream = new MemoryStream()) 73 { 74 using (ZipInputStream zipStream = new ZipInputStream(tempStream)) 75 { 76 zipStream.Password = password; 77 ZipEntry zipEntry = zipStream.GetNextEntry(); 78 79 if (zipEntry != null) 80 { 81 byte[] buffer = new byte[BufferSize]; 82 int readLength = 0; 83 84 do 85 { 86 readLength = zipStream.Read(buffer, 0, BufferSize); 87 writeStream.Write(buffer, 0, readLength); 88 } while (readLength == BufferSize); 89 90 writeStream.Flush(); 91 result = writeStream.ToArray(); 92 writeStream.Close(); 93 } 94 zipStream.Close(); 95 } 96 } 97 } 98 } 99 catch (System.Exception ex)100 {101 throw new Exception("解压字节数组发生错误", ex);102 }103 }104 return result;105 }
View Code

为了测试该类,我写了一个WinForm程序,界面如下:

SharpZipLib测试界面
可以将文件和文件夹拖放到压缩列表中,选中压缩列表中的对象可以按Delete键进行删除。文件解压区域也可以将要解压的文件拖放到文件路径输入文本框。实际测试可以正确压缩和解压,包括设置密码,压缩和解压操作和WinRAR完全兼容。如果您在代码中发现问题或有可以优化完善的地方,欢迎指出,谢谢!
程序源代码下载:
 
参考资料:
 

转载于:https://www.cnblogs.com/conexpress/p/SharpZipClass.html

你可能感兴趣的文章
【转载】K-NN算法 学习总结
查看>>
LeetCode - 445. Add Two Numbers II
查看>>
chrome jsonView插件安装
查看>>
【管用】 使用VMtools实现主机Windows与虚拟机Linux文件共享
查看>>
printk %pF %pS含义【转】
查看>>
C#使用ActiveMQ实例
查看>>
Spark的核心RDD(Resilient Distributed Datasets弹性分布式数据集)
查看>>
上海2017QCon个人分享总结
查看>>
自定义异常类。
查看>>
java 多线程并发 synchronized 同步机制及方式
查看>>
Python3.5爬取cbooo.cn数据并且同步到mysql中
查看>>
SQLServer性能优化专题
查看>>
tensorflow 线性回归解决 iris 2分类
查看>>
Maven的安装与配置
查看>>
腾讯云图片鉴黄集成到C# SQL Server 怎么在分页获取数据的同时获取到总记录数 sqlserver 操作数据表语句模板 .NET MVC后台发送post请求 百度api查询多个地址的经...
查看>>
[RK3288][Android6.0] USB OTG模式及切换【转】
查看>>
嘿!不用太过于担心的单点故障
查看>>
修改Ubuntu的aptget源为阿里源的方法
查看>>
Android Camera2 拍照入门学习
查看>>
Maven镜像更换为阿里云中央仓库
查看>>