Работа с ZIP-архивами в C# (.NET): создание, чтение и управление
В современных приложениях часто возникает необходимость сжимать файлы для экономии места или удобства передачи. Платформа .NET предоставляет мощные и удобные инструменты для работы с ZIP-архивами прямо из коробки. Используя пространство имен System.IO.Compression, вы можете легко создавать, извлекать и модифицировать архивы без установки сторонних библиотек. В этой статье мы подробно разберем все основные операции.
Подключение необходимых пространств имен
Для начала работы убедитесь, что в вашем проекте добавлены следующие директивы:
using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
Создание ZIP-архива
Самый простой способ создать архив — использовать класс ZipFile. Он доступен начиная с .NET Framework 4.5 и .NET Core.
Создание архива из одной папки
string sourceDirectory = @"C:\MyDocuments";
string zipFilePath = @"C:\MyArchive.zip";
// Создаем архив из всех файлов в указанной папке
ZipFile.CreateFromDirectory(sourceDirectory, zipFilePath);
Console.WriteLine("Архив создан: " + zipFilePath);
Создание архива с дополнительными параметрами
Вы можете указать уровень сжатия и добавить префикс пути внутри архива:
string sourceDir = @"C:\Data";
string outputZip = @"C:\Data.zip";
// CompressionLevel.Optimal - максимальное сжатие
// includeBaseDirectory: true - сохранит структуру папок
ZipFile.CreateFromDirectory(
sourceDir,
outputZip,
CompressionLevel.Optimal,
includeBaseDirectory: true
);
Console.WriteLine("Архив создан с оптимизацией.");
Извлечение файлов из архива
Распаковка всего архива в папку
string zipPath = @"C:\MyArchive.zip";
string extractPath = @"C:\ExtractedFiles";
// Распаковываем все содержимое
ZipFile.ExtractToDirectory(zipPath, extractPath);
Console.WriteLine("Архив успешно распакован.");
Распаковка с перезаписью существующих файлов
// В .NET 6+ можно указать перезапись
ZipFile.ExtractToDirectory(zipPath, extractPath, overwriteFiles: true);
Работа с отдельными записями в архиве
Класс ZipArchive дает полный контроль над содержимым архива.
Чтение списка файлов в архиве
using (ZipArchive archive = ZipFile.OpenRead(@"C:\Archive.zip"))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
Console.WriteLine($"Файл: {entry.FullName}, Размер: {entry.Length} байт");
}
}
Извлечение конкретного файла из архива
string zipFilePath = @"C:\Archive.zip";
string entryName = @"folder\document.txt"; // путь внутри архива
string outputPath = @"C:\Output\document.txt";
using (ZipArchive archive = ZipFile.OpenRead(zipFilePath))
{
ZipArchiveEntry entry = archive.GetEntry(entryName);
if (entry != null)
{
// Извлекаем файл
entry.ExtractToFile(outputPath, overwrite: true);
Console.WriteLine($"Файл '{entryName}' извлечен.");
}
else
{
Console.WriteLine("Файл не найден в архиве.");
}
}
Добавление и удаление файлов из существующего архива
Чтобы изменить существующий архив, откройте его в режиме ZipArchiveMode.Update:
Добавление нового файла в архив
string existingZip = @"C:\Archive.zip";
string fileToAdd = @"C:\NewFile.txt";
using (ZipArchive archive = ZipFile.Open(existingZip, ZipArchiveMode.Update))
{
// Добавляем файл с именем "NewFile.txt" в корень архива
archive.CreateEntryFromFile(fileToAdd, "NewFile.txt");
Console.WriteLine("Файл добавлен в архив.");
}
Удаление файла из архива
using (ZipArchive archive = ZipFile.Open(existingZip, ZipArchiveMode.Update))
{
ZipArchiveEntry entry = archive.GetEntry("OldFile.txt");
if (entry != null)
{
entry.Delete();
Console.WriteLine("Файл удален из архива.");
}
}
Работа с потоками (Stream)
Иногда удобнее работать напрямую с потоками, особенно если архив передается по сети или находится в памяти.
// Создаем архив в памяти
using (MemoryStream memoryStream = new MemoryStream())
{
using (ZipArchive archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, leaveOpen: true))
{
// Добавляем файл из строки
ZipArchiveEntry entry = archive.CreateEntry("Hello.txt");
using (StreamWriter writer = new StreamWriter(entry.Open()))
{
writer.WriteLine("Привет,