最近在网上查了一下在.net中进行压缩和解压缩的方法,方法有很多,我找到了以下几种:
1.利用.net自带的压缩和解压缩方法GZip
参考代码如下:
- //========================================================================
- // 类名: CommonCompress
- /// <summary>
- /// 用于对文件和字符串进行压缩
- /// </summary>
- /// <remarks>
- /// 用于对文件和字符串进行压缩
- /// </remarks>
- /*=======================================================================
- 变更记录
- 序号 更新日期 开发者 变更内容
- 0001 2008/07/22 张 新建
- =======================================================================*/
- public class CommonCompress
- {
- /// <summary>
- /// 压缩字符串
- /// </summary>
- /// <param name="strUncompressed">未压缩的字符串</param>
- /// <returns>压缩的字符串</returns>
- public static string StringCompress(string strUncompressed)
- {
- byte[] bytData = System.Text.Encoding.Unicode.GetBytes(strUncompressed);
- MemoryStream ms = new MemoryStream();
- Stream s = new GZipStream(ms, CompressionMode.Compress);
- s.Write(bytData, 0, bytData.Length);
- s.Close();
- byte[] dataCompressed = (byte[])ms.ToArray();
- return System.Convert.ToBase64String(dataCompressed, 0, dataCompressed.Length);
- }
- /// <summary>
- /// 解压缩字符串
- /// </summary>
- /// <param name="strCompressed">压缩的字符串</param>
- /// <returns>未压缩的字符串</returns>
- public static string StringDeCompress(string strCompressed)
- {
- System.Text.StringBuilder strUncompressed = new System.Text.StringBuilder();
- int totalLength = 0;
- byte[] bInput = System.Convert.FromBase64String(strCompressed); ;
- byte[] dataWrite = new byte[4096];
- Stream s = new GZipStream(new MemoryStream(bInput), CompressionMode.Decompress);
- while (true)
- {
- int size = s.Read(dataWrite, 0, dataWrite.Length);
- if (size > 0)
- {
- totalLength += size;
- strUncompressed.Append(System.Text.Encoding.Unicode.GetString(dataWrite, 0, size));
- }
- else
- {
- break;
- }
- }
- s.Close();
- return strUncompressed.ToString();
- }
- /// <summary>
- /// 压缩文件
- /// </summary>
- /// <param name="iFile">压缩前文件路径</param>
- /// <param name="oFile">压缩后文件路径</param>
- public static void CompressFile(string iFile, string oFile)
- {
- //判断文件是否存在
- if (File.Exists(iFile) == false)
- {
- throw new FileNotFoundException("文件未找到!");
- }
- //创建文件流
- byte[] buffer = null;
- FileStream iStream = null;
- FileStream oStream = null;
- GZipStream cStream = null;
- try
- {
- //把文件写进数组
- iStream = new FileStream(iFile, FileMode.Open, FileAccess.Read, FileShare.Read);
- buffer = new byte[iStream.Length];
- int num = iStream.Read(buffer, 0, buffer.Length);
- if (num != buffer.Length)
- {
- throw new ApplicationException("压缩文件异常!");
- }
- //创建文件输出流并输出
- oStream = new FileStream(oFile, FileMode.OpenOrCreate, FileAccess.Write);
- cStream = new GZipStream(oStream, CompressionMode.Compress, true);
- cStream.Write(buffer, 0, buffer.Length);
- }
- finally
- {
- //关闭流对象
- if (iStream != null) iStream.Close();
- if (cStream != null) cStream.Close();
- if (oStream != null) oStream.Close();
- }
- }
- /// <summary>
- /// 解压缩文件
- /// </summary>
- /// <param name="iFile">压缩前文件路径</param>
- /// <param name="oFile">压缩后文件路径</param>
- public static void DecompressFile(string iFile, string oFile)
- {
- //判断文件是否存在
- if (File.Exists(iFile) == false)
- {
- throw new FileNotFoundException("文件未找到!");
- }
- //创建文件流
- FileStream iStream = null;
- FileStream oStream = null;
- GZipStream dStream = null;
- byte[] qBuffer = new byte[4];
- try
- {
- //把压缩文件写入数组
- iStream = new FileStream(iFile, FileMode.Open);
- dStream = new GZipStream(iStream, CompressionMode.Decompress, true);
- int position = (int)iStream.Length - 4;
- iStream.Position = position;
- iStream.Read(qBuffer, 0, 4);
- iStream.Position = 0;
- int num = BitConverter.ToInt32(qBuffer, 0);
- byte[] buffer = new byte[num + 100];
- int offset = 0, total = 0;
- while (true)
- {
- int bytesRead = dStream.Read(buffer, offset, 100);
- if (bytesRead == 0) break;
- offset += bytesRead;
- total += bytesRead;
- }
- //创建输出流并输出
- oStream = new FileStream(oFile, FileMode.Create);
- oStream.Write(buffer, 0, total);
- oStream.Flush();
- }
- finally
- {
- //关闭流对象
- if (iStream != null) iStream.Close();
- if (dStream != null) dStream.Close();
- if (oStream != null) oStream.Close();
- }
- }
- }
2.利用ICSharpCode的压缩和解压缩方法,需引用ICSharpCode.SharpZipLib.dll,这个类库是开源的,源码地址http://www.icsharpcode.net/OpenSource/SharpZipLib/Download.aspx
参考代码如下:
- using System;
- using System.Collections.Generic;
- using System.IO;
- using ICSharpCode.SharpZipLib.Zip;
- using ICSharpCode.SharpZipLib.Checksums;
- namespace ZYBNET.FW.Utility.CommonMethod
- {
- //========================================================================
- // 类名: ZipHelper
- /// <summary>
- /// 用于对文件和字符串进行压缩
- /// </summary>
- /// <remarks>
- /// 用于对文件和字符串进行压缩
- /// </remarks>
- /*=======================================================================
- 变更记录
- 序号 更新日期 开发者 变更内容
- 0001 2008/07/22 张 新建
- =======================================================================*/
- public class ZipHelper
- {
- #region 压缩文件夹,支持递归
- /// <summary>
- /// 压缩文件夹
- /// </summary>
- /// <param name="dir">待压缩的文件夹</param>
- /// <param name="targetFileName">压缩后文件路径(包括文件名)</param>
- /// <param name="recursive">是否递归压缩</param>
- /// <returns></returns>
- public static bool Compress(string dir, string targetFileName, bool recursive)
- {
- //如果已经存在目标文件,询问用户是否覆盖
- if (File.Exists(targetFileName))
- {
- throw new Exception("同名文件已经存在!");
- }
- string[] ars = new string[2];
- if (recursive == false)
- {
- ars[0] = dir;
- ars[1] = targetFileName;
- return ZipFileDictory(ars);
- }
- FileStream zipFile;
- ZipOutputStream zipStream;
- //打开压缩文件流
- zipFile = File.Create(targetFileName);
- zipStream = new ZipOutputStream(zipFile);
- if (dir != String.Empty)
- {
- CompressFolder(dir, zipStream, dir);
- }
- //关闭压缩文件流
- zipStream.Finish();
- zipStream.Close();
- if (File.Exists(targetFileName))
- return true;
- else
- return false;
- }
- /// <summary>
- /// 压缩目录
- /// </summary>
- /// <param name="args">数组(数组[0]: 要压缩的目录; 数组[1]: 压缩的文件名)</param>
- public static bool ZipFileDictory(string[] args)
- {
- ZipOutputStream zStream = null;
- try
- {
- string[] filenames = Directory.GetFiles(args[0]);
- Crc32 crc = new Crc32();
- zStream = new ZipOutputStream(File.Create(args[1]));
- zStream.SetLevel(6);
- //循环压缩文件夹中的文件
- foreach (string file in filenames)
- {
- //打开压缩文件
- FileStream fs = File.OpenRead(file);
- byte[] buffer = new byte[fs.Length];
- fs.Read(buffer, 0, buffer.Length);
- ZipEntry entry = new ZipEntry(file);
- entry.DateTime = DateTime.Now;
- entry.Size = fs.Length;
- fs.Close();
- crc.Reset();
- crc.Update(buffer);
- entry.Crc = crc.Value;
- zStream.PutNextEntry(entry);
- zStream.Write(buffer, 0, buffer.Length);
- }
- }
- catch
- {
- throw;
- }
- finally
- {
- zStream.Finish();
- zStream.Close();
- }
- return true;
- }
- /// <summary>
- /// 压缩某个子文件夹
- /// </summary>
- /// <param name="basePath">待压缩路径</param>
- /// <param name="zips">压缩文件流</param>
- /// <param name="zipfolername">待压缩根路径</param>
- private static void CompressFolder(string basePath, ZipOutputStream zips, string zipfolername)
- {
- if (File.Exists(basePath))
- {
- AddFile(basePath, zips, zipfolername);
- return;
- }
- string[] names = Directory.GetFiles(basePath);
- foreach (string fileName in names)
- {
- AddFile(fileName, zips, zipfolername);
- }
- names = Directory.GetDirectories(basePath);
- foreach (string folderName in names)
- {
- CompressFolder(folderName, zips, zipfolername);
- }
- }
- /// <summary>
- /// 压缩某个子文件
- /// </summary>
- /// <param name="fileName">待压缩文件</param>
- /// <param name="zips">压缩流</param>
- /// <param name="zipfolername">待压缩根路径</param>
- private static void AddFile(string fileName, ZipOutputStream zips, string zipfolername)
- {
- if (File.Exists(fileName))
- {
- CreateZipFile(fileName, zips, zipfolername);
- }
- }
- /// <summary>
- /// 压缩单独文件
- /// </summary>
- /// <param name="FileToZip">待压缩文件</param>
- /// <param name="zips">压缩流</param>
- /// <param name="zipfolername">待压缩根路径</param>
- private static void CreateZipFile(string FileToZip, ZipOutputStream zips, string zipfolername)
- {
- try
- {
- FileStream StreamToZip = new FileStream(FileToZip, FileMode.Open, FileAccess.Read);
- string temp = FileToZip;
- string temp1 = zipfolername;
- if (temp1.Length > 0)
- {
- temp = temp.Replace(zipfolername + "\\", "");
- }
- ZipEntry ZipEn = new ZipEntry(temp);
- zips.PutNextEntry(ZipEn);
- byte[] buffer = new byte[16384];
- System.Int32 size = StreamToZip.Read(buffer, 0, buffer.Length);
- zips.Write(buffer, 0, size);
- try
- {
- while (size < StreamToZip.Length)
- {
- int sizeRead = StreamToZip.Read(buffer, 0, buffer.Length);
- zips.Write(buffer, 0, sizeRead);
- size += sizeRead;
- }
- }
- catch (System.Exception ex)
- {
- throw ex;
- }
- StreamToZip.Close();
- }
- catch
- {
- throw;
- }
- }
- #endregion
- #region 解压缩
- /// <summary>
- /// 功能:解压zip格式的文件。
- /// </summary>
- /// <param name="zipFilePath">压缩文件路径</param>
- /// <param name="unZipDir">解压文件存放路径,为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹</param>
- /// <returns>解压是否成功</returns>
- public static void UnZipFile(string zipFilePath, string unZipDir)
- {
- if (zipFilePath == string.Empty)
- {
- throw new Exception("压缩文件不能为空!");
- }
- if (!File.Exists(zipFilePath))
- {
- throw new Exception("压缩文件不存在!");
- }
- //解压文件夹为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹
- if (unZipDir == string.Empty)
- unZipDir = zipFilePath.Replace(Path.GetFileName(zipFilePath), Path.GetFileNameWithoutExtension(zipFilePath));
- if (!unZipDir.EndsWith("//"))
- unZipDir += "//";
- if (!Directory.Exists(unZipDir))
- Directory.CreateDirectory(unZipDir);
- try
- {
- using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipFilePath)))
- {
- ZipEntry theEntry;
- while ((theEntry = s.GetNextEntry()) != null)
- {
- string directoryName = Path.GetDirectoryName(theEntry.Name);
- string fileName = Path.GetFileName(theEntry.Name);
- if (directoryName.Length > 0)
- {
- Directory.CreateDirectory(unZipDir + directoryName);
- }
- if (!directoryName.EndsWith("//"))
- directoryName += "//";
- if (fileName != String.Empty)
- {
- using (FileStream streamWriter = File.Create(unZipDir + theEntry.Name))
- {
- int size = 2048;
- byte[] data = new byte[2048];
- while (true)
- {
- size = s.Read(data, 0, data.Length);
- if (size > 0)
- {
- streamWriter.Write(data, 0, size);
- }
- else
- {
- break;
- }
- }
- }
- }
- }
- }
- }
- catch
- {
- throw;
- }
- }
- #endregion
- }
- }
3.利用java的压缩和解压缩方法,需引用vjslib.dll
至于这种方法的使用,大家可以去查阅msdn,这里就不写了
4.利用zlibwapi.dll的API进行压缩
据说压缩效率比较好,但是在网上没找到供下载的链接,有兴趣的朋友可以试试
5.使用System.IO.Packaging压缩和解压
System.IO.Packaging在WindowsBase.dll程序集下,使用时需要添加对WindowsBase的引用
- /// <summary>
- /// Add a folder along with its subfolders to a Package
- /// </summary>
- /// <param name="folderName">The folder to add</param>
- /// <param name="compressedFileName">The package to create</param>
- /// <param name="overrideExisting">Override exsisitng files</param>
- /// <returns></returns>
- static bool PackageFolder(string folderName, string compressedFileName, bool overrideExisting)
- {
- if (folderName.EndsWith(@"\"))
- folderName = folderName.Remove(folderName.Length - 1);
- bool result = false;
- if (!Directory.Exists(folderName))
- {
- return result;
- }
- if (!overrideExisting && File.Exists(compressedFileName))
- {
- return result;
- }
- try
- {
- using (Package package = Package.Open(compressedFileName, FileMode.Create))
- {
- var fileList = Directory.EnumerateFiles(folderName, "*", SearchOption.AllDirectories);
- foreach (string fileName in fileList)
- {
- //The path in the package is all of the subfolders after folderName
- string pathInPackage;
- pathInPackage = Path.GetDirectoryName(fileName).Replace(folderName, string.Empty) + "/" + Path.GetFileName(fileName);
- Uri partUriDocument = PackUriHelper.CreatePartUri(new Uri(pathInPackage, UriKind.Relative));
- PackagePart packagePartDocument = package.CreatePart(partUriDocument,"", CompressionOption.Maximum);
- using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
- {
- fileStream.CopyTo(packagePartDocument.GetStream());
- }
- }
- }
- result = true;
- }
- catch (Exception e)
- {
- throw new Exception("Error zipping folder " + folderName, e);
- }
- return result;
- }
- /// <summary>
- /// Compress a file into a ZIP archive as the container store
- /// </summary>
- /// <param name="fileName">The file to compress</param>
- /// <param name="compressedFileName">The archive file</param>
- /// <param name="overrideExisting">override existing file</param>
- /// <returns></returns>
- static bool PackageFile(string fileName, string compressedFileName, bool overrideExisting)
- {
- bool result = false;
- if (!File.Exists(fileName))
- {
- return result;
- }
- if (!overrideExisting && File.Exists(compressedFileName))
- {
- return result;
- }
- try
- {
- Uri partUriDocument = PackUriHelper.CreatePartUri(new Uri(Path.GetFileName(fileName), UriKind.Relative));
- using (Package package = Package.Open(compressedFileName, FileMode.OpenOrCreate))
- {
- if (package.PartExists(partUriDocument))
- {
- package.DeletePart(partUriDocument);
- }
- PackagePart packagePartDocument = package.CreatePart(partUriDocument, "", CompressionOption.Maximum);
- using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
- {
- fileStream.CopyTo(packagePartDocument.GetStream());
- }
- }
- result = true;
- }
- catch (Exception e)
- {
- throw new Exception("Error zipping file " + fileName, e);
- }
- return result;
- }
- } 3、zip文件解压
- Code/// <summary>
- /// Extract a container Zip. NOTE: container must be created as Open Packaging Conventions (OPC) specification
- /// </summary>
- /// <param name="folderName">The folder to extract the package to</param>
- /// <param name="compressedFileName">The package file</param>
- /// <param name="overrideExisting">override existing files</param>
- /// <returns></returns>
- static bool UncompressFile(string folderName, string compressedFileName, bool overrideExisting)
- {
- bool result = false;
- try
- {
- if (!File.Exists(compressedFileName))
- {
- return result;
- }
- DirectoryInfo directoryInfo = new DirectoryInfo(folderName);
- if (!directoryInfo.Exists)
- directoryInfo.Create();
- using (Package package = Package.Open(compressedFileName, FileMode.Open, FileAccess.Read))
- {
- foreach (PackagePart packagePart in package.GetParts())
- {
- ExtractPart(packagePart, folderName, overrideExisting);
- }
- }
- result = true;
- }
- catch (Exception e)
- {
- throw new Exception("Error unzipping file " + compressedFileName, e);
- }
- return result;
- }
- static void ExtractPart(PackagePart packagePart, string targetDirectory, bool overrideExisting)
- {
- string stringPart = targetDirectory + HttpUtility.UrlDecode(packagePart.Uri.ToString()).Replace('\\', '/');
- if (!Directory.Exists(Path.GetDirectoryName(stringPart)))
- Directory.CreateDirectory(Path.GetDirectoryName(stringPart));
- if (!overrideExisting && File.Exists(stringPart))
- return;
- using (FileStream fileStream = new FileStream(stringPart, FileMode.Create))
- {
- packagePart.GetStream().CopyTo(fileStream);
- }
- }
6.在.NET 4.5使用ZipArchive、ZipFile等类压缩和解压
- static void Main(string[] args)
- {
- string ZipPath = @"c:\users\exampleuser\start.zip";
- string ExtractPath = @"c:\users\exampleuser\extract";
- string NewFile = @"c:\users\exampleuser\NewFile.txt";
- using (ZipArchive Archive = ZipFile.Open(ZipPath, ZipArchiveMode.Update))
- {
- Archive.CreateEntryFromFile(NewFile, "NewEntry.txt");
- Archive.ExtractToDirectory(ExtractPath);
- }
- }