当前位置:
首页 > Python基础教程 >
-
C#教程之【随笔系列】C#使用第三方SharpZipLib进行
近在做项目时用到了文件的批量压缩下载,使用了第三方的SharpZipLib包,后来想到了单个文件的压缩与解压,可能以后会用到相关技术,所以自己熟悉了一下并且借鉴了一些网上的相关代码,自己整理一下,这里我用到的是SharpZipLib 1.0.0版本,这里我新建一个控制台项目来展示。
一:创建项目并安装所需DLL
1、新建控制台项目ConsoleCompressApp
2、通过VisualStudio菜单中工具->NuGet包管理器->程序包管理控制台安装SharpZipLib包
命令是Install-Package SharpZipLib,如下图显示,已安装完成。
也可以通过鼠标选中项目然后右键弹出的菜单中选择管理NuGet程序包
选择第一个SharpZipLib包选择安装即可。
二:创建日志记录帮助类LogHelper
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 try 12 { 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 else 23 { 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 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 /// <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 try 16 { 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 do 45 { 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 /// <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 try 14 { 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 } 31 CompressTraversal(directory, outStream, ""); 32 outStream.Finish(); 33 } 34 } 35 } 36 catch (System.Exception ex) 37 { 38 LogHelper.Write(ex.ToString()); 39 } 40 } 41 42 /// <summary> 43 /// 压缩文件夹,并返回压缩后的文件数据流 44 /// </summary> 45 /// <param name="directory">待压缩文件夹(绝对路径)</param> 46 /// <param name="isEncrypt">是否加密,默认加密</param> 47 /// <param name="encryptPassword">加密的密码(为空不进行加密)</param> 48 public static byte[] CompressDirectoryBytes(string directory, bool isEncrypt, string encryptPassword = "") 49 { 50 if (Directory.Exists(directory) == false) throw new DirectoryNotFoundException("未能找到当前路径!"); 51 try 52 { 53 ///获取待压缩文件名称 54 string name = new DirectoryInfo(directory).Name; 55 56 byte[] buffer = null; 57 58 MemoryStream ms = new MemoryStream(); 59 ZipOutputStream outStream = new ZipOutputStream(ms); 60 if (isEncrypt) 61 { 62 ///压缩文件加密 63 outStream.Password = encryptPassword; 64 } 65 CompressTraversal(directory, outStream, ""); 66 outStream.Finish(); 67 68 buffer = new byte[ms.Length]; 69 ms.Seek(0, SeekOrigin.Begin); 70 ms.Read(buffer, 0, (int)ms.Length); 71 return buffer; 72 } 73 catch (System.Exception ex) 74 { 75 LogHelper.Write(ex.ToString()); 76 return null; 77 } 78 } 79 80 /// <summary> 81 /// 递归遍历目录 82 /// </summary> 83 private static void CompressTraversal(string directory, ZipOutputStream outStream, string parentDirectory) 84 { 85 ///判断路径最后一个字符是否为当前系统的DirectorySeparatorChar 86 if (directory[directory.Length - 1] != Path.DirectorySeparatorChar) 87 { 88 directory += Path.DirectorySeparatorChar; 89 } 90 Crc32 crc = new Crc32(); 91 var fileOrDirectory = Directory.GetFileSystemEntries(directory); 92 ///遍历文件与目录 93 foreach (var item in fileOrDirectory) 94 { 95 ///判断是否为目录 96 if (Directory.Exists(item)) 97 { 98 CompressTraversal(item, outStream, (parentDirectory + item.Substring(item.LastIndexOf(Path.DirectorySeparatorChar) + 1) + Path.DirectorySeparatorChar)); 99 } 100 ///压缩文件 101 else 102 { 103 using (FileStream inStream = File.OpenRead(item)) 104 { 105 ///缓存区对象 106 byte[] buffer = new byte[inStream.Length]; 107 ///将流重置 108 inStream.Seek(0, SeekOrigin.Begin); 109 ///从文件流中读取字节,将该数据写入缓存区 110 inStream.Read(buffer, 0, (int)inStream.Length); 111 ///获取该文件名称(附带文件目录结构,例如git\\git.exe) 112 string fileName = parentDirectory + item.Substring(item.LastIndexOf(Path.DirectorySeparatorChar) + 1); 113 ///创建zip条目 114 ZipEntry entry = new ZipEntry(fileName); 115 entry.DateTime = DateTime.Now; 116 entry.Size = inStream.Length; 117 118 crc.Reset(); 119 crc.Update(buffer); 120 121 entry.Crc = crc.Value; 122 123 outStream.PutNextEntry(entry); 124 ///将缓存区对象数据写入流中 125 outStream.Write(buffer, 0, buffer.Length); 126 ///注意:一定要关闭当前条目,否则压缩包数据会丢失 127 outStream.CloseEntry(); 128 } 129 } 130 } 131 }
4、最后添加解压的静态方法
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("未能找到目标路径!"
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式