Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 2

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

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

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

Ответ 3

Вы захотите использовать стороннюю библиотеку, например 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.1, DotNetZip включает в себя собственный DeflateStream, который более эффективен, чем тот, который поставляется в .NET Framework. В качестве дополнительного преимущества встроенный DeflateStream в DotNetZip позволяет использовать DotNetZip на .NET Compact Framework 2.0, в котором отсутствует System.IO.Compression.DeflateStream. (он был добавлен в Compact Framework 3.5)

Там есть хороший форум на сайте DotNetZip, если у вас больше вопросов. Пример кода С#:

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

Ответ 4

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

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

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

Ответ 5

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

Ответ 7

Да, я использовал его в прошлом. Я подклассифицировал 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);
}

Ответ 8

    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);
        }
    }