Разархивируйте файлы программно в .net - PullRequest
198 голосов
/ 08 мая 2009

Я пытаюсь распаковать архивированный файл.

Я пытался использовать класс System.IO.Compression.GZipStream в .NET, но когда мое приложение запускается (на самом деле модульный тест), я получаю следующее исключение:

System.IO.InvalidDataException: магическое число в заголовке GZip неверно. Убедитесь, что вы передаете поток GZip.

Теперь я понимаю, что файл .zip не совпадает с файлом .gz, и что GZip не совпадает с Zip.

Однако, поскольку я могу извлечь файл, дважды щелкнув вручную сжатый файл и затем нажав кнопку «Извлечь все файлы», я думаю, что в коде должен быть способ сделать это.

Поэтому я попытался использовать Process.Start() с путем к архивному файлу в качестве ввода. Это заставляет мое приложение открывать окно, показывающее содержимое в заархивированном файле. Это все нормально, но приложение будет установлено на сервере, который не нажимает кнопку «Извлечь все файлы».

Итак, как мне заставить мое приложение извлекать файлы в заархивированных файлах?

Или есть другой способ сделать это? Я предпочитаю делать это в коде, без загрузки каких-либо сторонних библиотек или приложений; отдел безопасности не слишком увлекается этим ...

Ответы [ 15 ]

451 голосов
/ 01 февраля 2013

С .NET 4.5 теперь вы можете разархивировать файлы с помощью .NET Framework:

using System;
using System.IO;

namespace ConsoleApplication
{
  class Program
  {
    static void Main(string[] args)
    {
      string startPath = @"c:\example\start";
      string zipPath = @"c:\example\result.zip";
      string extractPath = @"c:\example\extract";

      System.IO.Compression.ZipFile.CreateFromDirectory(startPath, zipPath);
      System.IO.Compression.ZipFile.ExtractToDirectory(zipPath, extractPath);
    }
  }
}

Приведенный выше код был взят непосредственно из документации Microsoft: http://msdn.microsoft.com/en-us/library/ms404280(v=vs.110).aspx

ZipFile содержится в сборке System.IO.Compression.FileSystem. (Спасибо nateirvin ... см. Комментарий ниже)

78 голосов
/ 04 июня 2015

Для .Net 4.5 +

Не всегда желательно записывать несжатый файл на диск. Как разработчику ASP.Net, мне пришлось бы возиться с разрешениями, чтобы предоставить права на запись моего приложения в файловую систему. Работая с потоками в памяти, я могу обойти все это и читать файлы напрямую:

using (ZipArchive archive = new ZipArchive(postedZipStream))
{
    foreach (ZipArchiveEntry entry in archive.Entries)
    {
         var stream = entry.Open();
         //Do awesome stream stuff!!
    }
}

Кроме того, вы все равно можете записать распакованный файл на диск, вызвав ExtractToFile():

using (ZipArchive archive = ZipFile.OpenRead(pathToZip))
{
    foreach (ZipArchiveEntry entry in archive.Entries)
    {
        entry.ExtractToFile(Path.Combine(destination, entry.FullName));
    }
} 

Чтобы использовать класс ZipArchive, вам необходимо добавить ссылку на пространство имен System.IO.Compression и на System.IO.Compression.FileSystem.

52 голосов
/ 08 мая 2009

Мы успешно использовали SharpZipLib во многих проектах. Я знаю, что это сторонний инструмент, но исходный код включен и может дать некоторую информацию, если вы решите изобретать колесо здесь.

51 голосов
/ 14 сентября 2012

Бесплатно, и никаких внешних DLL файлов. Все в одном файле CS. Одна загрузка - это просто файл CS, другая загрузка - очень простой для понимания пример. Просто попробовал сегодня, и я не могу поверить, насколько простой была установка. Сработало с первой попытки, без ошибок, без ничего.

https://github.com/jaime-olivares/zipstorer

27 голосов
/ 08 мая 2009

Используйте библиотеку DotNetZip на http://www.codeplex.com/DotNetZip

библиотека классов и набор инструментов для работы с zip-файлами. Используйте VB, C # или любой другой язык .NET для простого создания, извлечения или обновления zip-файлов ...

DotNetZip работает на ПК с полной версией .NET Framework, а также на мобильных устройствах, использующих .NET Compact Framework. Создавать и читать zip-файлы на VB, C # или любом другом языке .NET или в любой среде сценариев ...

Если все, что вам нужно, это лучший класс DeflateStream или GZipStream, который заменит тот, который встроен в .NET BCL, то DotNetZip также имеет это. DlateNetZip DeflateStream и GZipStream доступны в отдельной сборке на основе порта .NET Zlib. Эти потоки поддерживают уровни сжатия и обеспечивают гораздо лучшую производительность, чем встроенные классы. Существует также ZlibStream для завершения набора (RFC 1950, 1951, 1952) ...

9 голосов
/ 03 октября 2017
String ZipPath = @"c:\my\data.zip";
String extractPath = @"d:\\myunzips";
ZipFile.ExtractToDirectory(ZipPath, extractPath);

Чтобы использовать класс ZipFile, вы должны добавить ссылку на сборку System.IO.Compression.FileSystem в вашем проекте

2 голосов
/ 08 мая 2009

Стандартные zip-файлы обычно используют алгоритм deflate.

Для извлечения файлов без использования сторонних библиотек используйте DeflateStream. Вам понадобится немного больше информации о формате архива zip-файла, поскольку Microsoft предоставляет только алгоритм сжатия.

Вы также можете попробовать использовать zipfldr.dll. Это библиотека сжатия Microsoft (сжатые папки из меню «Отправить»). Похоже, это библиотека, но она недокументирована. Возможно, вам удастся заставить его работать на себя с помощью экспериментов.

1 голос
/ 29 марта 2019

Это сделает это System.IO.Compression.ZipFile.ExtractToDirectory(ZipName, ExtractToPath)

1 голос
/ 12 мая 2014

Вы можете сделать все это в .NET 3.5, используя DeflateStream. В .NET 3.5 не хватает возможности обрабатывать разделы заголовков файлов, которые используются для организации сжатых файлов. PKWare опубликовал эту информацию, которую вы можете использовать для обработки zip-файла после создания используемых структур. Это не особенно обременительно, и это хорошая практика в создании инструментов без использования стороннего кода.

Это не однострочный ответ, но это вполне выполнимо, если вы хотите и можете не торопиться. Я написал для этого класс за пару часов, и из этого я получил возможность архивировать и распаковывать файлы только с использованием .NET 3.5.

1 голос
/ 13 сентября 2013

Я использую это, чтобы сжать или разархивировать несколько файлов. Regex не требуется, но я использую его для изменения отметки даты и удаления нежелательных подчеркиваний. Я использую пустую строку в строке Compress >> zipPath для добавления префикса ко всем файлам, если это необходимо. Кроме того, я обычно комментирую либо Compress (), либо Decompress () в зависимости от того, что я делаю.

using System;
using System.IO.Compression;
using System.IO;
using System.Text.RegularExpressions;

namespace ZipAndUnzip
{
    class Program
    {
        static void Main(string[] args)
        {
            var directoryPath = new DirectoryInfo(@"C:\your_path\");

            Compress(directoryPath);
            Decompress(directoryPath);
        }

        public static void Compress(DirectoryInfo directoryPath)
        {
            foreach (DirectoryInfo directory in directoryPath.GetDirectories())
            {
                var path = directoryPath.FullName;
                var newArchiveName = Regex.Replace(directory.Name, "[0-9]{8}", "20130913");
                newArchiveName = Regex.Replace(newArchiveName, "[_]+", "_");
                string startPath = path + directory.Name;
                string zipPath = path + "" + newArchiveName + ".zip";

                ZipFile.CreateFromDirectory(startPath, zipPath);
            }

        }

        public static void Decompress(DirectoryInfo directoryPath)
        {
            foreach (FileInfo file in directoryPath.GetFiles())
            {
                var path = directoryPath.FullName;
                string zipPath = path + file.Name;
                string extractPath = Regex.Replace(path + file.Name, ".zip", "");

                ZipFile.ExtractToDirectory(zipPath, extractPath);
            }
        }


    }
}
...