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

StackOverflow https://stackoverflow.com/questions/184309

  •  06-07-2019
  •  | 
  •  

Вопрос

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

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

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

Это было полезно?

Решение

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

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

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

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

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

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

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

Сторонние библиотеки, такие как DotNetZip, обрабатывают метаданные в ZIP-архиве. Они могут использовать или не использовать класс System.IO.Compression.DeflateStream () для создания сжатого потока байтов. Например, в предыдущих выпусках DotNetZip использовала встроенный DeflateStream. Начиная с v1.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);
    }

Начиная с .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 как потоков, способных или читать и записывать без шага извлечения и сжатия файлов.

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

Я использовал класс GZipStream (в то время я понимал, что соответствующий DeflateStream был просто GZip без информации заголовка или чем-то подобным & # 8212; я уверен, что кто-то может исправить меня в этом). Это работает довольно просто, добавляя к вершине другой поток, и таким образом вы используете вместо него 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);
}
    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);
        }
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top