Как создавать и распаковывать zip-файлы (сжимать и распаковывать zip) с помощью SharpZipLib с C # в WinForms

SharpZipLib или ранее NZipLib — это библиотека Zip, GZip, Tar и BZip2, полностью написанная на C # для платформы .NET. Он реализован как сборка (устанавливается в GAC) и, следовательно, может быть легко включен в другие проекты (на любом языке .NET). Создатель ziplib выразился так:

Я перенес библиотеку zip на C #, потому что мне нужно было сжатие gzip / zip, и я не хотел использовать libzip.dll или что-то подобное. Я хочу все в чистом C #.

Конечно, есть инструменты по умолчанию для этого в .NET (по крайней мере, для файлов ZIP), такие как System.IO.Compressionоднако он не предлагает все функции, которые есть у зрелой библиотеки, такой как SharpZipLib, например использование пароля для защиты файлов и т. д. В этой статье мы расскажем вам, как установить библиотеку в Visual Studio и как ее выполнить. Типичные задачи с файлами ZIP, как их создание или извлечение.

1. Установите SharpZipLib через NuGet

Первое, что вам нужно сделать, это установить библиотеку в ваш проект через nuGet. Откройте проект Winforms C # и откройте менеджер пакетов NuGet в обозревателе решений:

Перейдите на вкладку Обзор и найдите SharpZipLib:

SharpZipLib Winforms c #

Из списка выберите пакет по ICSharpCode и установите его. После завершения установки пакета вы сможете использовать его на своих занятиях. ziplib изначально был разработан Майком Крюгером, однако большая часть существующего Java-кода очень помогла в ускорении создания этой библиотеки. Поэтому кредиты вылетают другим людям. Текущий опекун ziplib — Дэвид Пирсон. Пожалуйста, свяжитесь с ним относительно особенностей, ошибок и т. Д. Через форум или же официальный репозиторий на Github здесь.

2. Использование библиотеки

Заметка

В этой статье мы будем работать только с ZIP-файлами, однако помните, что библиотека работает с различными форматами сжатия, такими как TAR, GZip и т. Д.

После установки вам нужно будет импортировать пространства имен, которые требуются для создания ZIP-файлов, а именно:

using System.IO;
using ICSharpCode.SharpZipLib.Zip;

Примеры

Как обычно в Нашем мире кода, фрагмент кода означает более тысячи слов, поэтому в примерах мы покажем, как вы можете решить большинство типичных задач при работе с файлами ZIP с C #.

Создать .zip из всех файлов в папке

Следующий метод compressDirectory показывает, как сжать все файлы в каталоге (путь строки) и прикрепить их в один zip-файл. В качестве первого аргумента метод ожидает каталог, в котором находятся файлы, в качестве второго аргумента — путь к файлу .zip, который будет сгенерирован, и в качестве последнего (необязательно) уровень сжатия (0-9):

using System.IO;
using ICSharpCode.SharpZipLib.Zip;
///
/// Method that compress all the files inside a folder (non-recursive) into a zip file.
///
///
///
///
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 с паролем из всех файлов в папке

Если вы хотите определить пароль для сгенерированного файла, вам нужно только установить Password собственность ZipOutputStream экземпляр с паролем в строковом формате:

///
/// Method that compress all the files inside a folder (non-recursive) into a zip file.
///
///
///
///
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-файла внутри определенной папки. Первый аргумент указывает путь к файлу, который вы хотите распаковать, второй аргумент — пароль файла (вы можете установить его на ноль, если файл не защищен паролем) и в качестве последнего аргумента путь к папке, где содержимое файла должно быть извлечено:

///
/// Extracts the content from a .zip file inside an specific folder.
///
///
///
///
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, которым вы, возможно, захотите поделиться с сообществом, или вам нужно что-то, связанное с использованием этой библиотеки, не стесняйтесь и делитесь своими советами в поле для комментариев.

Ссылка на основную публикацию
Adblock
detector