C# GZipStream 压缩 解压
关于GZipStream压缩解压,网上找了很多资料,完整的不多,要么是针对字符串压缩解压缩的,要么只实现了针对单个文件的压缩解压缩,还有的不支持子文件夹的压缩,实用性都不是很大。
以下整理了压缩解压缩的代码,供以后拿出来翻阅,在项目中可以直接使用这3个类,已通过测试。
1.首先是有一个描述要压缩的文件类GZipFileInfo,包含了一些文件信息
/// <summary>
/// 要压缩的文件信息
/// </summary>
public class GZipFileInfo
{
/// <summary>
/// 文件索引
/// </summary>
public int Index = 0;
/// <summary>
/// 文件相对路径,'/'
/// </summary>
public string RelativePath = null;
public DateTime ModifiedDate;
/// <summary>
/// 文件内容长度
/// </summary>
public int Length = 0;
public bool AddedToTempFile = false;
public bool RestoreRequested = false;
public bool Restored = false;
/// <summary>
/// 文件绝对路径,'\'
/// </summary>
public string LocalPath = null;
public string Folder = null;
public bool ParseFileInfo(string fileInfo)
{
bool success = false;
try
{
if (!string.IsNullOrEmpty(fileInfo))
{
// get the file information
string[] info = fileInfo.Split(',');
if (info != null && info.Length == 4)
{
this.Index = Convert.ToInt32(info[0]);
this.RelativePath = info[1].Replace("/", "\\");
this.ModifiedDate = Convert.ToDateTime(info[2]);
this.Length = Convert.ToInt32(info[3]);
success = true;
}
}
}
catch
{
success = false;
}
return success;
}
}
2.压缩后生成的压缩包信息GZipResult,描述了压缩包的一些属性,包括大小,文件数,以及其中的每一个文件
/// <summary>
/// 文件压缩后的压缩包类
/// </summary>
public class GZipResult
{
/// <summary>
/// 压缩包中包含的所有文件,包括子目录下的文件
/// </summary>
public GZipFileInfo[] Files = null;
/// <summary>
/// 要压缩的文件数
/// </summary>
public int FileCount = 0;
public long TempFileSize = 0;
public long ZipFileSize = 0;
/// <summary>
/// 压缩百分比
/// </summary>
public int CompressionPercent = 0;
/// <summary>
/// 临时文件
/// </summary>
public string TempFile = null;
/// <summary>
/// 压缩文件
/// </summary>
public string ZipFile = null;
/// <summary>
/// 是否删除临时文件
/// </summary>
public bool TempFileDeleted = false;
public bool Errors = false;
}
3.压缩操作类GZip,包括压缩解压等操作
/// <summary>/// 压缩文件类/// </summary>public class GZip{ /// <summary> /// Compress /// </summary> /// <param name="lpSourceFolder">The location of the files to include in the zip file, all files including files in subfolders will be included.</param> /// <param name="lpDestFolder">Folder to write the zip file into</param> /// <param name="zipFileName">Name of the zip file to write</param> public static GZipResult Compress(string lpSourceFolder, string lpDestFolder, string zipFileName) { return Compress(lpSourceFolder, "*.*", SearchOption.AllDirectories, lpDestFolder, zipFileName, true); } /// <summary> /// Compress /// </summary> /// <param name="lpSourceFolder">The location of the files to include in the zip file</param> /// <param name="searchPattern">Search pattern (ie "*.*" or "*.txt" or "*.gif") to idendify what files in lpSourceFolder to include in the zip file</param> /// <param name="searchOption">Only files in lpSourceFolder or include files in subfolders also</param> /// <param name="lpDestFolder">Folder to write the zip file into</param> /// <param name="zipFileName">Name of the zip file to write</param> /// <param name="deleteTempFile">Boolean, true deleted the intermediate temp file, false leaves the temp file in lpDestFolder (for debugging)</param> public static GZipResult Compress(string lpSourceFolder, string searchPattern, SearchOption searchOption, string lpDestFolder, string zipFileName, bool deleteTempFile) { DirectoryInfo di = new DirectoryInfo(lpSourceFolder); FileInfo[] files = di.GetFiles("*.*", searchOption); return Compress(files, lpSourceFolder, lpDestFolder, zipFileName, deleteTempFile); } /// <summary> /// Compress /// </summary> /// <param name="files">Array of FileInfo objects to be included in the zip file</param> /// <param name="lpBaseFolder">Base folder to use when creating relative paths for the files /// stored in the zip file. For example, if lpBaseFolder is 'C:\zipTest\Files\', and there is a file /// 'C:\zipTest\Files\folder1\sample.txt' in the 'files' array, the relative path for sample.txt /// will be 'folder1/sample.txt'</param> /// <param name="lpDestFolder">Folder to write the zip file into</param> /// <param name="zipFileName">Name of the zip file to write</param> public static GZipResult Compress(FileInfo[] files, string lpBaseFolder, string lpDestFolder, string zipFileName) { return Compress(files, lpBaseFolder, lpDestFolder, zipFileName, true); } /// <summary> /// Compress /// </summary> /// <param name="files">Array of FileInfo objects to be included in the zip file</param> /// <param name="lpBaseFolder">Base folder to use when creating relative paths for the files /// stored in the zip file. For example, if lpBaseFolder is 'C:\zipTest\Files\', and there is a file /// 'C:\zipTest\Files\folder1\sample.txt' in the 'files' array, the relative path for sample.txt /// will be 'folder1/sample.txt'</param> /// <param name="lpDestFolder">Folder to write the zip file into</param> /// <param name="zipFileName">Name of the zip file to write</param> /// <param name="deleteTempFile">Boolean, true deleted the intermediate temp file, false leaves the temp file in lpDestFolder (for debugging)</param> public static GZipResult Compress(FileInfo[] files, string lpBaseFolder, string lpDestFolder, string zipFileName, bool deleteTempFile) { GZipResult result = new GZipResult(); try { if (!lpDestFolder.EndsWith("\\")) { lpDestFolder += "\\"; } string lpTempFile = lpDestFolder + zipFileName + ".tmp"; string lpZipFile = lpDestFolder + zipFileName; result.TempFile = lpTempFile; result.ZipFile = lpZipFile; if (files != null && files.Length > 0) { CreateTempFile(files, lpBaseFolder, lpTempFile, result); if (result.FileCount > 0) { CreateZipFile(lpTempFile, lpZipFile, result); } // delete the temp file if (deleteTempFile) { File.Delete(lpTempFile); result.TempFileDeleted = true; } } } catch //(Exception ex4) { result.Errors = true; } return result; } private static void CreateZipFile(string lpSourceFile, string lpZipFile, GZipResult result) { byte[] buffer; int count = 0; FileStream fsOut = null; FileStream fsIn = null; GZipStream gzip = null; // compress the file into the zip file try { fsOut = new FileStream(lpZipFile, FileMode.Create, FileAccess.Write, FileShare.None); gzip = new GZipStream(fsOut, CompressionMode.Compress, true); fsIn = new FileStream(lpSourceFile, FileMode.Open, FileAccess.Read, FileShare.Read); buffer = new byte[fsIn.Length]; count = fsIn.Read(buffer, 0, buffer.Length); fsIn.Close(); fsIn = null; // compress to the zip file gzip.Write(buffer, 0, buffer.Length); result.ZipFileSize = fsOut.Length; result.CompressionPercent = GetCompressionPercent(result.TempFileSize, result.ZipFileSize); } catch //(Exception ex1) { result.Errors = true; } finally { if (gzip != null) { gzip.Close(); gzip = null; } if (fsOut != null) { fsOut.Close(); fsOut = null; } if (fsIn != null) { fsIn.Close(); fsIn = null; } } } private static void CreateTempFile(FileInfo[] files, string lpBaseFolder, string lpTempFile, GZipResult result) { byte[] buffer; int count = 0; byte[] header; string fileHeader = null; string fileModDate = null; string lpFolder = null; int fileIndex = 0; string lpSourceFile = null; string vpSourceFile = null; GZipFileInfo gzf = null; FileStream fsOut = null; FileStream fsIn = null; if (files != null && files.Length > 0) { try { result.Files = new GZipFileInfo[files.Length]; // open the temp file for writing fsOut = new FileStream(lpTempFile, FileMode.Create, FileAccess.Write, FileShare.None); foreach (FileInfo fi in files) { lpFolder = fi.DirectoryName + "\\"; try { gzf = new GZipFileInfo(); gzf.Index = fileIndex; // read the source file, get its virtual path within the source folder lpSourceFile = fi.FullName; gzf.LocalPath = lpSourceFile; vpSourceFile = lpSourceFile.Replace(lpBaseFolder, string.Empty); vpSourceFile = vpSourceFile.Replace("\\", "/"); gzf.RelativePath = vpSourceFile; fsIn = new FileStream(lpSourceFile, FileMode.Open, FileAccess.Read, FileShare.Read); buffer = new byte[fsIn.Length]; count = fsIn.Read(buffer, 0, buffer.Length); fsIn.Close(); fsIn = null; fileModDate = fi.LastWriteTimeUtc.ToString(); gzf.ModifiedDate = fi.LastWriteTimeUtc; gzf.Length = buffer.Length; fileHeader = fileIndex.ToString() + "," + vpSourceFile + "," + fileModDate + "," + buffer.Length.ToString() + "\n"; header = Encoding.Default.GetBytes(fileHeader); fsOut.Write(header, 0, header.Length); fsOut.Write(buffer, 0, buffer.Length); fsOut.WriteByte(10); // linefeed gzf.AddedToTempFile = true; // update the result object result.Files[fileIndex] = gzf; // increment the fileIndex fileIndex++; } catch //(Exception ex1) { result.Errors = true; } finally { if (fsIn != null) { fsIn.Close(); fsIn = null; } } if (fsOut != null) { result.TempFileSize = fsOut.Length; } } } catch //(Exception ex2) { result.Errors = true; } finally { if (fsOut != null) { fsOut.Close(); fsOut = null; } } } result.FileCount = fileIndex; } public static GZipResult Decompress(string lpSourceFolder, string lpDestFolder, string zipFileName) { return Decompress(lpSourceFolder, lpDestFolder, zipFileName, true, true, null, null, 4096); } public static GZipResult Decompress(string lpSourceFolder, string lpDestFolder, string zipFileName, bool writeFiles, string addExtension) { return Decompress(lpSourceFolder, lpDestFolder, zipFileName, true, writeFiles, addExtension, null, 4096); } public static GZipResult Decompress(string lpSrcFolder, string lpDestFolder, string zipFileName, bool deleteTempFile, bool writeFiles, string addExtension, Hashtable htFiles, int bufferSize) { GZipResult result = new GZipResult(); if (!lpDestFolder.EndsWith("\\")) { lpDestFolder += "\\"; } string lpTempFile = lpSrcFolder + zipFileName + ".tmp"; string lpZipFile = lpSrcFolder + zipFileName; result.TempFile = lpTempFile; result.ZipFile = lpZipFile; string line = null; string lpFilePath = null; string lpFolder = null; GZipFileInfo gzf = null; FileStream fsTemp = null; ArrayList gzfs = new ArrayList(); bool write = false; if (string.IsNullOrEmpty(addExtension)) { addExtension = string.Empty; } else if (!addExtension.StartsWith(".")) { addExtension = "." + addExtension; } // extract the files from the temp file try { fsTemp = UnzipToTempFile(lpZipFile, lpTempFile, result); if (fsTemp != null) { while (fsTemp.Position != fsTemp.Length) { line = null; while (string.IsNullOrEmpty(line) && fsTemp.Position != fsTemp.Length) { line = ReadLine(fsTemp); } if (!string.IsNullOrEmpty(line)) { gzf = new GZipFileInfo(); if (gzf.ParseFileInfo(line) && gzf.Length > 0) { gzfs.Add(gzf); lpFilePath = lpDestFolder + gzf.RelativePath; lpFolder = GetFolder(lpFilePath); gzf.LocalPath = lpFilePath; write = false; if (htFiles == null || htFiles.ContainsKey(gzf.RelativePath)) { gzf.RestoreRequested = true; write = writeFiles; } if (write) { // make sure the folder exists if (!Directory.Exists(lpFolder)) { Directory.CreateDirectory(lpFolder); } // read from fsTemp and write out the file gzf.Restored = WriteFile(fsTemp, gzf.Length, lpFilePath + addExtension, bufferSize); } else { // need to advance fsTemp fsTemp.Position += gzf.Length; } } } } } } catch //(Exception ex3) { result.Errors = true; } finally { if (fsTemp != null) { fsTemp.Close(); fsTemp = null; } } // delete the temp file try { if (deleteTempFile) { File.Delete(lpTempFile); result.TempFileDeleted = true; } } catch //(Exception ex4) { result.Errors = true; } result.FileCount = gzfs.Count; result.Files = new GZipFileInfo[gzfs.Count]; gzfs.CopyTo(result.Files); return result; } private static string ReadLine(FileStream fs) { string line = string.Empty; const int bufferSize = 4096; byte[] buffer = new byte[bufferSize]; byte b = 0; byte lf = 10; int i = 0; while (b != lf) { b = (byte)fs.ReadByte(); buffer[i] = b; i++; } line = System.Text.Encoding.Default.GetString(buffer, 0, i - 1); return line; } private static bool WriteFile(FileStream fs, int fileLength, string lpFile, int bufferSize) { bool success = false; FileStream fsFile = null; if (bufferSize == 0 || fileLength < bufferSize) { bufferSize = fileLength; } int count = 0; int remaining = fileLength; int readSize = 0; try { byte[] buffer = new byte[bufferSize]; fsFile = new FileStream(lpFile, FileMode.Create, FileAccess.Write, FileShare.None); while (remaining > 0) { if (remaining > bufferSize) { readSize = bufferSize; } else { readSize = remaining; } count = fs.Read(buffer, 0, readSize); remaining -= count; if (count == 0) { break; } fsFile.Write(buffer, 0, count); fsFile.Flush(); } fsFile.Flush(); fsFile.Close(); fsFile = null; success = true; } catch //(Exception ex2) { success = false; } finally { if (fsFile != null) { fsFile.Flush(); fsFile.Close(); fsFile = null; } } return success; } private static string GetFolder(string lpFilePath) { string lpFolder = lpFilePath; int index = lpFolder.LastIndexOf("\\"); if (index != -1) { lpFolder = lpFolder.Substring(0, index + 1); } return lpFolder; } private static FileStream UnzipToTempFile(string lpZipFile, string lpTempFile, GZipResult result) { FileStream fsIn = null; GZipStream gzip = null; FileStream fsOut = null; FileStream fsTemp = null; const int bufferSize = 4096; byte[] buffer = new byte[bufferSize]; int count = 0; try { fsIn = new FileStream(lpZipFile, FileMode.Open, FileAccess.Read, FileShare.Read); result.ZipFileSize = fsIn.Length; fsOut = new FileStream(lpTempFile, FileMode.Create, FileAccess.Write, FileShare.None); gzip = new GZipStream(fsIn, CompressionMode.Decompress, true); while (true) { count = gzip.Read(buffer, 0, bufferSize); if (count != 0) { fsOut.Write(buffer, 0, count); } if (count != bufferSize) { break; } } } catch //(Exception ex1) { result.Errors = true; } finally { if (gzip != null) { gzip.Close(); gzip = null; } if (fsOut != null) { fsOut.Close(); fsOut = null; } if (fsIn != null) { fsIn.Close(); fsIn = null; } } fsTemp = new FileStream(lpTempFile, FileMode.Open, FileAccess.Read, FileShare.None); if (fsTemp != null) { result.TempFileSize = fsTemp.Length; } return fsTemp; } private static int GetCompressionPercent(long tempLen, long zipLen) { double tmp = (double)tempLen; double zip = (double)zipLen; double hundred = 100; double ratio = (tmp - zip) / tmp; double pcnt = ratio * hundred; return (int)pcnt; }} |
压缩解压缩的操作如下:
//Compress三个参数分别是“要压缩的目标目录”,“保存压缩文件的目录”,压缩文件名
GZip.Compress(@"E:\much\", @"E:\much\", "ziptest");
//Decompress三个参数分别是"压缩包所在目录","要解压到的目录",“压缩包名”
//如果压缩包所在目录不存在则解压不会成功
GZip.Decompress(@"E:\much\zip\", @"E:\much\zip\", "ziptest");
C# GZipStream 压缩 解压的更多相关文章
- WebAPI性能优化之压缩解压
有时候为了提升WebAPI的性能,减少响应时间,我们会使用压缩和解压,而现在大多数客户端浏览器都提供了内置的解压支持.在WebAPI请求的资源越大时,使用压缩对性能提升的效果越明显,而当请求的资源很小 ...
- (转载)C#压缩解压zip 文件
转载之: C#压缩解压zip 文件 - 大气象 - 博客园http://www.cnblogs.com/greatverve/archive/2011/12/27/csharp-zip.html C# ...
- 字符串GZIP压缩解压
c# /// <summary> /// 字符串压缩解压 /// </summary> public class Zipper { public static string C ...
- Linux 压缩解压
压缩解压 ------------------------------------------ linux 下所有的压缩格式,WinRAR 都支持 gzip .gz 格式 压缩文件: gzip 文件名 ...
- SAPCAR 压缩解压软件的使用方法
SAPCAR 是 SAP 公司使用的压缩解压软件,从 SAP 网站下载的补丁包和小型软件基本都是扩展名为 car 或 sar 的,它们都可以用 SAPCAR 来解压.下面是它的使用说明: 用法: 创建 ...
- 对称加密之AES、压缩解压以及压缩加密解密解压综合实战
AES 压缩解压 压缩加密解密解压 对称加密: 就是采用这种加密方法的双方使用方式用同样的密钥进行加密和解密.密钥是控制加密及解密过程的指令.算法是一组规则,规定如何进行加密和解密. 因此加密的安 ...
- linux笔记:linux常用命令-压缩解压命令
压缩解压命令:gzip(压缩文件,不保留原文件.这个命令不能压缩目录) 压缩解压命令:gunzip(解压.gz的压缩文件) 压缩解压命令:tar(打包压缩目录或者解压压缩文件.打包的意思是把目录打包成 ...
- .NET使用ICSharpCode.SharpZipLib压缩/解压文件
SharpZipLib是国外开源加压解压库,可以方便的对文件进行加压/解压 1.下载ICSharpCode.SharpZipLib.dll,并复制到bin目录下 http://www.icsharpc ...
- linux驱动系列之文件压缩解压小节(转)
转至网页:http://www.jb51.net/LINUXjishu/43356.html Linux下最常用的打包程序就是tar了,使用tar程序打出来的包我们常称为tar包,tar包文件的命令通 ...
随机推荐
- line-height 行高的使用
line-height:normal; 默认 字体 line-height:1.5; line-height:200%; line-height:50px; ps : 固定的值 line-heig ...
- 使用sqlyog工具同步两个相同结构的数据库之间的数据
compare two database data 因为工作上遇到 同一个项目被部署到不同服务器上,原项目(后统称"源")在运行中,后部署的项目(后统称"目标" ...
- vue 学习四 了解组件
1组件的注册 全局注册 import Vue from 'vue'; import com from './component1'; Vue.component("com_name" ...
- ES6-let cont 关键字
***let1. 作用: * 与var类似, 用于声明一个变量2. 特点: * 在块作用域内有效 * 不能重复声明 * 不会预处理, 不存在提升3. 应用: * 循环遍历加监听 * 使用let取代va ...
- 【SGU194】Reactor Cooling
题目大意 给定一个无源无汇的网络,边的容量有上下界限制,试构造一个合理的流量. 题目分析 求无源汇上下界的可行流模板题. ①增加一个附加源和汇\(S,T\). ②把每个节点的\(\sum b_{u,i ...
- Centos7.5 安装sonarqube-7.1
下载sonarqube-7.1 wget -t 0 -c https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-7.1.z ...
- 牛客多校第三次B——线段树维护线性基交
写线性基交函数时调试了半天.. #include<bits/stdc++.h> using namespace std; #define ll long long #define maxn ...
- 其它课程中的python---4、Matplotlib最最最最简单使用
其它课程中的python---4.Matplotlib最最最最简单使用 一.总结 一句话总结: 慢慢来吧,不着急,心态平和和沉稳:每次和世界交互,你就能感受到无比的自信 1.如何区别python2和p ...
- 在vs2010下编译boost
1. 解压缩后,运行bootstrap.bat批处理文件,得到bjam.exe; 2. 在vs2010下编译boost boost最新版本已经支持vs2010,然而直接下载编译会发现一堆bug: 首先 ...
- 2.用Python套用Excel模板,一键完成原亮样式
from xlutils.copy import copy import xlrd import xlwt tem_excel=xlrd.open_workbook('日统计.xls',formatt ...