用了第二种方法,感觉很不错,其他都没用过了。摘录下来,做一个备忘。
最近在网上查了一下在.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); } }