用c#自带的System.IO.Compression命名空间下的压缩类实现的多文件压缩和解压功能,缺点是多文件压缩包的解压只能调用自身的解压方法,和现有的压缩软件不兼容。下面的代码没有把多文件的目录结构加进去,有需要的可以自己改下。
using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; namespace Test.Zip { class CompressHelper { /// <summary> /// 单文件压缩(生成的压缩包和第三方的解压软件兼容) /// </summary> /// <param name="sourceFilePath"></param> /// <returns></returns> public string CompressSingle(string sourceFilePath) { string zipFileName = sourceFilePath + ".gz"; using (FileStream sourceFileStream = new FileInfo(sourceFilePath).OpenRead()) { using (FileStream zipFileStream = File.Create(zipFileName)) { using (GZipStream zipStream = new GZipStream(zipFileStream, CompressionMode.Compress)) { sourceFileStream.CopyTo(zipStream); } } } return zipFileName; } /// <summary> /// 自定义多文件压缩(生成的压缩包和第三方的压缩文件解压不兼容) /// </summary> /// <param name="sourceFileList">文件列表</param> /// <param name="saveFullPath">压缩包全路径</param> public void CompressMulti(string[] sourceFileList, string saveFullPath) { MemoryStream ms = new MemoryStream(); foreach (string filePath in sourceFileList) { Console.WriteLine(filePath); if (File.Exists(filePath)) { string fileName = Path.GetFileName(filePath); byte[] fileNameBytes = System.Text.Encoding.UTF8.GetBytes(fileName); byte[] sizeBytes = BitConverter.GetBytes(fileNameBytes.Length); ms.Write(sizeBytes, 0, sizeBytes.Length); ms.Write(fileNameBytes, 0, fileNameBytes.Length); byte[] fileContentBytes = System.IO.File.ReadAllBytes(filePath); ms.Write(BitConverter.GetBytes(fileContentBytes.Length), 0, 4); ms.Write(fileContentBytes, 0, fileContentBytes.Length); } } ms.Flush(); ms.Position = 0; using (FileStream zipFileStream = File.Create(saveFullPath)) { using (GZipStream zipStream = new GZipStream(zipFileStream, CompressionMode.Compress)) { ms.Position = 0; ms.CopyTo(zipStream); } } ms.Close(); } /// <summary> /// 多文件压缩解压 /// </summary> /// <param name="zipPath">压缩文件路径</param> /// <param name="targetPath">解压目录</param> public void DeCompressMulti(string zipPath, string targetPath) { byte[] fileSize = new byte[4]; if (File.Exists(zipPath)) { using (FileStream fStream = File.Open(zipPath, FileMode.Open)) { using (MemoryStream ms = new MemoryStream()) { using (GZipStream zipStream = new GZipStream(fStream, CompressionMode.Decompress)) { zipStream.CopyTo(ms); } ms.Position = 0; while (ms.Position != ms.Length) { ms.Read(fileSize, 0, fileSize.Length); int fileNameLength = BitConverter.ToInt32(fileSize, 0); byte[] fileNameBytes = new byte[fileNameLength]; ms.Read(fileNameBytes, 0, fileNameBytes.Length); string fileName = System.Text.Encoding.UTF8.GetString(fileNameBytes); string fileFulleName = targetPath + fileName; ms.Read(fileSize, 0, 4); int fileContentLength = BitConverter.ToInt32(fileSize, 0); byte[] fileContentBytes = new byte[fileContentLength]; ms.Read(fileContentBytes, 0, fileContentBytes.Length); using (FileStream childFileStream = File.Create(fileFulleName)) { childFileStream.Write(fileContentBytes, 0, fileContentBytes.Length); } } } } } } } }
调用示例:
List<string> strList = new List<string>() { @"D:\文档\soapUI工程\Synchro-soapui-project.xml", @"D:\文档\soapUI工程\PKBSML-soapui-project.xml", @"D:\文档\soapUI工程\PKBSML-soapui-project.xml" }; var zipHelper = new Test.Zip.CompressHelper(); zipHelper.CompressMulti(strList.ToArray(), @"D:\wulala.gz"); zipHelper.DeCompressMulti(@"D:\wulala.gz", @"D:\web\");