如何在WinForms中使用C#使用SharpZipLib创建和提取zip文件(压缩和解压缩zip)

本文概述

  • 1.通过NuGet安装SharpZipLib
  • 2.使用库
  • 例子
【如何在WinForms中使用C#使用SharpZipLib创建和提取zip文件(压缩和解压缩zip)】SharpZipLib或以前的NZipLib是完全用C#为.NET平台编写的Zip, GZip, Tar和BZip2库。它实现为程序集(可在GAC中安装), 因此可以轻松地并入其他项目(使用任何.NET语言)。 ziplib的创建者这样说:
我已将zip库移植到C#, 因为我需要gzip / zip压缩, 而且我不想使用libzip.dll或类似的东西。我想要全部使用纯C#。
当然, 在.NET中(至少对于ZIP文件而言)确实有默认工具, 例如System.IO.Compression, 但是它不提供像SharpZipLib这样的成熟库喜欢使用密码来保护文件的所有功能。等。在本文中, 我们将与你分享如何在Visual Studio中安装库以及如何在创建或提取ZIP文件时使用ZIP文件完成典型任务。
1.通过NuGet安装SharpZipLib 首先, 你需要通过nuGet在你的项目中安装该库。打开你的Winforms C#项目, 然后在解决方案资源管理器中打开NuGet程序包管理器:
如何在WinForms中使用C#使用SharpZipLib创建和提取zip文件(压缩和解压缩zip)

文章图片
转到浏览选项卡并搜索SharpZipLib:
如何在WinForms中使用C#使用SharpZipLib创建和提取zip文件(压缩和解压缩zip)

文章图片
从列表中选择ICSharpCode软件包并安装。软件包安装完成后, 你将可以在课堂上使用它。 ziplib最初是由Mike Krueger开发的, 但是, 许多现有的Java代码在很大程度上帮助加快了该库的创建速度。因此, 荣誉归于他人。ziplib的当前维护者是David Pierson。请通过论坛或Github上的官方存储库与他联系, 以获取有关功能, 错误等的信息。
2.使用库 注意 在本文中, 我们将仅使用ZIP文件, 但是请记住该库可使用TAR, GZip等不同的压缩格式。
基本上, 安装后, 你将需要导入创建ZIP文件所需的命名空间, 即:
using System.IO; using ICSharpCode.SharpZipLib.Zip;

例子 像在《我们的代码世界》中一样, 一个代码片段意味着一千多个单词, 因此我们将在示例中展示如何在使用C#处理ZIP文件时如何完成大多数的关键任务。
从文件夹内的所有文件创建.zip
以下方法compressDirectory显示如何压缩目录(字符串路径)中的所有文件并将它们附加到单个zip文件中。该方法将文件所在的目录作为第一个参数, 将第二个参数作为将要生成的.zip文件的路径, 最后一个(可选)压缩级别(0-9):
using System.IO; using ICSharpCode.SharpZipLib.Zip; /// < summary> /// Method that compress all the files inside a folder (non-recursive) into a zip file./// < /summary> /// < param name="DirectoryPath"> < /param> /// < param name="OutputFilePath"> < /param> /// < param name="CompressionLevel"> < /param> private void compressDirectory(string DirectoryPath, string OutputFilePath, int CompressionLevel = 9){try{// Depending on the directory this could be very large and would require more attention// in a commercial package.string[] filenames = Directory.GetFiles(DirectoryPath); // 'using' statements guarantee the stream is closed properly which is a big source// of problems otherwise.Its exception safe as well which is great.using (ZipOutputStream OutputStream = new ZipOutputStream(File.Create(OutputFilePath))){// Define the compression level// 0 - store only to 9 - means best compressionOutputStream.SetLevel(CompressionLevel); byte[] buffer = new byte[4096]; foreach (string file in filenames){// Using GetFileName makes the result compatible with XP// as the resulting path is not absolute.ZipEntry entry = new ZipEntry(Path.GetFileName(file)); // Setup the entry data as required.// Crc and size are handled by the library for seakable streams// so no need to do them here.// Could also use the last write time or similar for the file.entry.DateTime = DateTime.Now; OutputStream.PutNextEntry(entry); using (FileStream fs = File.OpenRead(file)){// Using a fixed size buffer here makes no noticeable difference for output// but keeps a lid on memory usage.int sourceBytes; do{sourceBytes = fs.Read(buffer, 0, buffer.Length); OutputStream.Write(buffer, 0, sourceBytes); } while (sourceBytes > 0); }}// Finish/Close arent needed strictly as the using statement does this automatically// Finish is important to ensure trailing information for a Zip file is appended.Without this// the created file would be invalid.OutputStream.Finish(); // Close is important to wrap things up and unlock the file.OutputStream.Close(); Console.WriteLine("Files successfully compressed"); }}catch (Exception ex){// No need to rethrow the exception as for our purposes its handled.Console.WriteLine("Exception during processing {0}", ex); }}

可以像这样使用:
compressDirectory(@"C:\Users\user\Desktop\SomeFolder", @"C:\Users\user\Desktop\SomeFolder\MyOutputFile.zip", 9);

从文件夹内的所有文件中使用密码创建.zip
如果要为生成的文件定义密码, 则只需使用字符串格式的密码设置ZipOutputStream实例的Password属性:
/// < summary> /// Method that compress all the files inside a folder (non-recursive) into a zip file./// < /summary> /// < param name="DirectoryPath"> < /param> /// < param name="OutputFilePath"> < /param> /// < param name="CompressionLevel"> < /param> private void compressDirectoryWithPassword(string DirectoryPath, string OutputFilePath, string Password = null, int CompressionLevel = 9){try{// Depending on the directory this could be very large and would require more attention// in a commercial package.string[] filenames = Directory.GetFiles(DirectoryPath); // 'using' statements guarantee the stream is closed properly which is a big source// of problems otherwise.Its exception safe as well which is great.using (ZipOutputStream OutputStream = new ZipOutputStream(File.Create(OutputFilePath))){// Define a password for the file (if providen)// set its value to null or don't declare it to leave the file// without password protectionOutputStream.Password = Password; // Define the compression level// 0 - store only to 9 - means best compressionOutputStream.SetLevel(CompressionLevel); byte[] buffer = new byte[4096]; foreach (string file in filenames){// Using GetFileName makes the result compatible with XP// as the resulting path is not absolute.ZipEntry entry = new ZipEntry(Path.GetFileName(file)); // Setup the entry data as required.// Crc and size are handled by the library for seakable streams// so no need to do them here.// Could also use the last write time or similar for the file.entry.DateTime = DateTime.Now; OutputStream.PutNextEntry(entry); using (FileStream fs = File.OpenRead(file)){// Using a fixed size buffer here makes no noticeable difference for output// but keeps a lid on memory usage.int sourceBytes; do{sourceBytes = fs.Read(buffer, 0, buffer.Length); OutputStream.Write(buffer, 0, sourceBytes); } while (sourceBytes > 0); }}// Finish/Close arent needed strictly as the using statement does this automatically// Finish is important to ensure trailing information for a Zip file is appended.Without this// the created file would be invalid.OutputStream.Finish(); // Close is important to wrap things up and unlock the file.OutputStream.Close(); Console.WriteLine("Files successfully compressed"); }}catch (Exception ex){// No need to rethrow the exception as for our purposes its handled.Console.WriteLine("Exception during processing {0}", ex); }}

这种方法可以像这样使用:
// Or to use without password:// string PasswordForZipFile = null; string PasswordForZipFile = "ourcodeworld123"; compressDirectoryWithPassword(@"C:\Users\user\Desktop\Folders", @"C:\Users\user\Desktop\Folders\DestinationFile.zip", PasswordForZipFile, 9);

在这种情况下, 密码” ourcodeworld123″ 将保护对zip文件内容的访问。
将.zip内容提取到文件夹
以下方法提取特定文件夹内的zip文件的内容。第一个参数指定要解压缩的文件的路径, 第二个参数是文件的密码(如果文件没有密码保护, 则可以将其设置为null), 最后一个参数是文件夹的路径, 其中文件内容应提取:
/// < summary> /// Extracts the content from a .zip file inside an specific folder./// < /summary> /// < param name="FileZipPath"> < /param> /// < param name="password"> < /param> /// < param name="OutputFolder"> < /param> public void ExtractZipContent(string FileZipPath, string password, string OutputFolder){ZipFile file = null; try{FileStream fs = File.OpenRead(FileZipPath); file = new ZipFile(fs); if (!String.IsNullOrEmpty(password)){// AES encrypted entries are handled automaticallyfile.Password = password; }foreach (ZipEntry zipEntry in file){if (!zipEntry.IsFile){// Ignore directoriescontinue; }String entryFileName = zipEntry.Name; // to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName); // Optionally match entrynames against a selection list here to skip as desired.// The unpacked length is available in the zipEntry.Size property.// 4K is optimumbyte[] buffer = new byte[4096]; Stream zipStream = file.GetInputStream(zipEntry); // Manipulate the output filename here as desired.String fullZipToPath = Path.Combine(OutputFolder, entryFileName); string directoryName = Path.GetDirectoryName(fullZipToPath); if (directoryName.Length > 0){Directory.CreateDirectory(directoryName); }// Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size// of the file, but does not waste memory.// The "using" will close the stream even if an exception occurs.using (FileStream streamWriter = File.Create(fullZipToPath)){StreamUtils.Copy(zipStream, streamWriter, buffer); }}}finally{if (file != null){file.IsStreamOwner = true; // Makes close also shut the underlying streamfile.Close(); // Ensure we release resources}}}

可以像这样使用:
// If the file doesn't have passwordExtractZipContent(@"C:\Users\user\Desktop\SomeFolder\TheFileToDecompress.zip", null, @"C:\Users\user\Desktop\outputfolder"); // If the file has passwordExtractZipContent(@"C:\Users\user\Desktop\SomeFolder\TheFileToDecompress.zip", "password123", @"C:\Users\user\Desktop\outputfolder");

如果你想与SharpZipLib共享另一个有用的片段, 或者你需要与该库的使用相关的内容, 请不要害羞, 并在评论框中分享你的想法。
编码愉快!

    推荐阅读