本文概述
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程序包管理器:
转到浏览选项卡并搜索SharpZipLib:
从列表中选择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 compression
OutputStream.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 protection
OutputStream.Password = Password;
// Define the compression level
// 0 - store only to 9 - means best compression
OutputStream.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 automatically
file.Password = password;
}
foreach (ZipEntry zipEntry in file)
{
if (!zipEntry.IsFile)
{
// Ignore directories
continue;
}
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 optimum
byte[] 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 stream
file.Close(); // Ensure we release resources
}
}
}
可以像这样使用:
// If the file doesn't have password
ExtractZipContent(
@"C:\Users\user\Desktop\SomeFolder\TheFileToDecompress.zip", null, @"C:\Users\user\Desktop\outputfolder"
);
// If the file has password
ExtractZipContent(
@"C:\Users\user\Desktop\SomeFolder\TheFileToDecompress.zip", "password123", @"C:\Users\user\Desktop\outputfolder"
);
如果你想与SharpZipLib共享另一个有用的片段, 或者你需要与该库的使用相关的内容, 请不要害羞, 并在评论框中分享你的想法。
编码愉快!
评论前必须登录!
注册