Как использовать System.IO.Compression для чтения / записи файлов ZIP?

Я знаю, что есть библиотеки для работы с ZIP-файлами. И вы можете в качестве альтернативы использовать встроенную в Windows функциональность для работы с ZIP-файлами.

Но мне интересно, придумал ли кто-нибудь, как использовать инструменты, встроенные в пространство имен System.IO.Compression в .NET, для чтения / записи файлов ZIP? Или невозможно использовать только это пространство имен?

ОБНОВЛЕНО: мне кажется, кто-то комментирует, что пространство имен System.IO.Packaging также может быть полезно с этим. Кто-нибудь точно знает, как это сделать?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
20
0
90 406
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Ответ принят как подходящий

MSDN имеет полный примерhttp://msdn.microsoft.com/en-us/library/system.io.packaging.zippackage.aspx с использованием класса ZipPackage. Требуется .NET 3.5.

Фактически, пространство имен System.IO.Packaging содержит классы для работы с пакетами в стиле Open Packaging. Вы можете использовать его для создания ZIP-файлов (если вам не нужны дополнительные файлы, которые будут включены в ваш ZIP-архив), но его нельзя использовать для открытия zip-файла Любые. Для получения дополнительной информации см. внизу документации класса ZipPackage (это сообщество отсутствует в документе .NET 4.0, но все еще действует).

larsmoa 16.03.2012 16:50

Дэйв, очень мило !! Я не знал, что это там было.

Теперь, когда я знаю, что искать, я смог найти статью с небольшим примером кода о том, как его использовать: http://weblogs.asp.net/jgalloway/archive/2007/10/25/creating-zip-archives-in-net-without-an-external-library-like-sharpziplib.aspx

Кстати, я также обнаружил, что Проект DotNetZip выглядит чрезвычайно простым в использовании.

Да, я использовал его раньше. Я создал подкласс DataSet один раз, чтобы поддерживать сохранение себя в файле (с помощью метода ReadXML / WriteXML). В качестве дополнительного бонуса я решил при желании сделать возможным его сжатие (как вы все уже должны знать, это чрезвычайно эффективно с текстовыми данными, такими как XML).

Я использовал класс GZipStream (в то время я понимал, что связанный с ним DeflateStream был просто GZip без информации заголовка или чего-то подобного - я уверен, что кто-то может исправить меня в этом). Он работает довольно просто, подкрепляясь поверх другого потока, и поэтому вы затем используете GZipStream вместо него. В моем случае это было связано с FileStream.

Учитывая, что MemoryStream заполняется выводом myDataSet.WriteXML(), я сделал что-то вроде следующего:

if (CompressData)
{
    // Write to memory
    mStream = new MemoryStream();
    Save(mStream);
    mStream.Seek(0, SeekOrigin.Begin);

    // Filter that through a GZipStream and then to file
    fStream = new FileStream(Path.Combine(CacheFilePath, FileName + ".gz"),
                             FileMode.OpenOrCreate);
    zipStream = new GZipStream(fStream, CompressionMode.Compress, true);

    Pump(mStream, zipStream);
}
else
{
    // Write straight to file
    fStream = new FileStream(Path.Combine(CacheFilePath, FileName),
                             FileMode.OpenOrCreate);
    Save(fStream);
}

Где Save() и Pump() - это простые методы, подобные следующему:

private void Pump(Stream input, Stream output)
{
    int n;
    byte[] bytes = new byte[4096]; // 4KiB at a time

    while ((n = input.Read(bytes, 0, bytes.Length)) != 0)
    {
        output.Write(bytes, 0, n);
    }
}

public void Save(Stream stream)
{
    AcceptChanges();

    WriteXml(stream, XmlWriteMode.WriteSchema);
}

Ваше решение не читает и не записывает в формат файла ZIP, а просто в необработанное сжатие deflate или простое расширение верхнего колонтитула GZip вокруг сжатия deflate.

Martin Plante 09.10.2008 04:02

+1 ваш ответ может не создавать ZIP-файлы, но он показывает, как использовать System.IO.Compression, который отлично подходит для сжатия файлов в SSIS, где вы ограничены .NET 2.0 и трудно использовать внешние библиотеки.

bstoney 19.09.2011 06:15

Вы захотите использовать стороннюю библиотеку, такую ​​как http://www.codeplex.com/DotNetZip, вместо того, чтобы пытаться использовать GZipStream или DeflateStream для чтения zip-файла.

Классы *** Stream в .NET позволяют читать или записывать сжатые потоки байтов. Эти классы НЕ читают и не записывают zip-файлы. ZIP-файл - это сжатые данные, окруженные «конвертом» или заголовком. Думайте об этом как о метаданных - они включают имя файла, временную метку, CRC и множество других вещей. Классы ** Stream создают только поток сжатых данных и не знают, как создавать или использовать метаданные, что описано в спецификации формата PKZip, поддерживаемой PKWare.

Сторонние библиотеки, такие как DotNetZip, обрабатывают метаданные в ZIP-архиве. Они могут использовать или не использовать класс System.IO.Compression.DeflateStream () для создания сжатого потока байтов. В предыдущих выпусках, например, DotNetZip использовал встроенный DeflateStream. Начиная с версии 1.7, DotNetZip включает собственный DeflateStream, который более эффективен, чем тот, который поставляется в .NET Framework. В качестве дополнительного преимущества встроенный DeflateStream в DotNetZip позволяет использовать DotNetZip в .NET Compact Framework 2.0, в котором отсутствует System.IO.Compression.DeflateStream. (он был добавлен в Compact Framework 3.5)

На сайте DotNetZip есть хороший форум, если у вас есть еще вопросы. Пример кода C#:

    try
    {
        using (ZipFile zip = new ZipFile())
        {
            zip.AddDirectory(DirectoryToZip); // recurses subdirs
            zip.Save(Filename);
        }
    }
    catch (System.Exception ex1)
    {
        System.Console.Error.WriteLine("exception: " + ex1);
    }

    public static void zIpDatabseFile(string srcPath, string destPath)
    {//This is for  Zip a File
        using (var source = new FileStream(srcPath, FileMode.Open, FileAccess.Read, FileShare.Read))
        using (var dest = new FileStream(destPath, FileMode.OpenOrCreate, FileAccess.Write))
        using (var zip = new GZipStream(dest, CompressionMode.Compress))
        {
            source.CopyTo(zip);
        }
    }
    public static void uNzIpDatabaseFile(string SrcPath, string DestPath)
    {// This is for unzip a files.
        using (var source = new FileStream(SrcPath, FileMode.Open, FileAccess.Read, FileShare.Read))
        using (var dest = new FileStream(DestPath, FileMode.OpenOrCreate, FileAccess.Write))
        using (var zip = new GZipStream(source, CompressionMode.Decompress))
        {
            zip.CopyTo(dest);
        }
    }

Начиная с .NET 4.5, Microsoft предложила класс ZipArchive пространству имен System.IO.Compression. Однако, в отличие от других классов в этом пространстве имен, таких как поток GZipStream и Deflate, сборка ZipArchiveтребуется ссылка на System.IO.Compression.dll.

Его довольно просто использовать, и приведенная выше ссылка на MSDN предоставляет несколько хороших примеров.

Кроме того, Microsoft создала Пакет Microsoft Compression NuGet, который добавляет поддержку ZipArchive и связанных классов в Windows Phone 8 и другие библиотеки переносимых классов.

Я знаю, что это более старая ветка, но я хотел бы отметить, что .NET 4.5 внес значительные улучшения в system.io.compression. Теперь он может довольно хорошо манипулировать файлами .zip, вплоть до представления отдельных файлов в zip-архиве в виде потоков, способных читать и писать без этапа извлечения и сжатия файлов.

Другие вопросы по теме