Работа с ZIP-архивами в C# (.NET)
В современной разработке на платформе .NET работа с архивами — одна из часто встречающихся задач. Будь то упаковка логов, создание резервных копий или передача данных по сети — умение эффективно сжимать и распаковывать файлы необходимо каждому C#-разработчику. В этой статье мы подробно разберём два основных подхода: встроенное пространство имён System.IO.Compression и стороннюю библиотеку SharpZipLib.
Встроенные средства .NET: System.IO.Compression
Начиная с .NET Framework 4.5, платформа предоставляет нативный API для работы с ZIP-архивами. Основные классы находятся в пространстве имён System.IO.Compression.
Создание ZIP-архива
Для создания архива используется класс ZipArchive в паре с ZipFile:
using System.IO;
using System.IO.Compression;
string sourceDirectory = @"C:\Data\Reports";
string zipPath = @"C:\Archives\reports.zip";
if (File.Exists(zipPath))
File.Delete(zipPath);
ZipFile.CreateFromDirectory(sourceDirectory, zipPath);
Console.WriteLine("Архив создан: " + zipPath);
Извлечение архива
Распаковка выполняется аналогично — методом ExtractToDirectory:
string extractPath = @"C:\Data\Extracted";
ZipFile.ExtractToDirectory(zipPath, extractPath);
Console.WriteLine("Архив извлечён в: " + extractPath);
Работа с отдельными записями
Для более тонкого контроля используйте ZipArchive напрямую:
using (FileStream zipStream = new FileStream(zipPath, FileMode.Open))
using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Read))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
Console.WriteLine($"Файл: {entry.FullName}, Размер: {entry.Length} байт");
// Извлечение конкретного файла
entry.ExtractToFile(Path.Combine(extractPath, entry.FullName), true);
}
}
Библиотека SharpZipLib
SharpZipLib — это мощная сторонняя библиотека с открытым исходным кодом, предоставляющая расширенные возможности по сравнению со встроенными средствами. Она поддерживает больше форматов (GZip, BZip2, Tar) и даёт более гибкий контроль над процессом сжатия.
Установка SharpZipLib
Установите библиотеку через NuGet Package Manager:
Install-Package SharpZipLib
Или через .NET CLI:
dotnet add package SharpZipLib
Создание архива с SharpZipLib
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Core;
string outputZip = @"C:\Archives\backup.zip";
string[] filesToZip = Directory.GetFiles(@"C:\Data\Files", "*.*", SearchOption.AllDirectories);
using (FileStream fsOut = File.Create(outputZip))
using (ZipOutputStream zipStream = new ZipOutputStream(fsOut))
{
zipStream.SetLevel(9); // Максимальное сжатие (0-9)
foreach (string filename in filesToZip)
{
FileInfo fi = new FileInfo(filename);
string entryName = ZipEntry.CleanName(fi.Name);
ZipEntry newEntry = new ZipEntry(entryName);
newEntry.DateTime = fi.LastWriteTime;
newEntry.Size = fi.Length;
zipStream.PutNextEntry(newEntry);
byte[] buffer = new byte[4096];
using (FileStream fsInput = File.OpenRead(filename))
{
StreamUtils.Copy(fsInput, zipStream, buffer);
}
zipStream.CloseEntry();
}
}
Извлечение архива с SharpZipLib
string inputZip = @"C:\Archives\backup.zip";
string outputDir = @"C:\Data\Restored";
using (FileStream fsIn = File.OpenRead(inputZip))
using (ZipInputStream zipStream = new ZipInputStream(fsIn))
{
ZipEntry entry;
while ((entry = zipStream.GetNextEntry()) != null)
{
if (!entry.IsDirectory)
{
string fullPath = Path.Combine(outputDir, entry.Name);
string dirName = Path.GetDirectoryName(fullPath);
if (!Directory.Exists(dirName))
Directory.CreateDirectory(dirName);
byte[] buffer = new byte[4096];
using (FileStream streamWriter = File.Create(fullPath))
{
StreamUtils.Copy(zipStream, streamWriter, buffer);
}
}
}
}
Сравнение подходов
Выбор между встроенными средствами и SharpZipLib зависит от конкретных задач:
- System.IO.Compression — идеален для простых операций: создать архив, извлечь все файлы, прочитать метаданные. Не требует установки дополнительных пакетов.
- SharpZipLib — рекомендуется для сложных сценариев: работа с большими архивами, потоковое