Как я могу перечислить содержимое папки .zip в c #? - PullRequest
28 голосов
/ 21 ноября 2008

Как я могу перечислить содержимое архива в C #? Например, как узнать, сколько элементов содержится в заархивированной папке и как они называются?

Ответы [ 8 ]

32 голосов
/ 21 ноября 2008

DotNetZip - манипулирование Zip-файлами на языках .NET

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

пример кода для чтения почтового индекса:

using (var zip = ZipFile.Read(PathToZipFolder))
{
    int totalEntries = zip.Entries.Count; 
    foreach (ZipEntry e in zip.Entries)
    {
        e.FileName ...
        e.CompressedSize ...
        e.LastModified...
    }
}
25 голосов
/ 14 февраля 2014

.NET 4.5 или новее, наконец, имеет встроенную возможность обрабатывать общие zip-файлы с классом System.IO.Compression.ZipArchive (http://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive%28v=vs.110%29.aspx) в сборке System.IO.Compression. Нет необходимости в какой-либо сторонней библиотеке.

string zipPath = @"c:\example\start.zip";
using (ZipArchive archive = ZipFile.OpenRead(zipPath))
{
    foreach (ZipArchiveEntry entry in archive.Entries)
    {
        Console.WriteLine(entry.FullName);
    }
} 
21 голосов
/ 21 ноября 2008

Если вы используете .Net Framework 3.0 или более позднюю версию, проверьте System.IO.Packaging Namespace . Это снимет вашу зависимость от внешней библиотеки.

Специально проверьте Класс ZipPackage .

12 голосов
/ 21 ноября 2008

Регистрация в SharpZipLib

ZipInputStream inStream = new ZipInputStream(File.OpenRead(fileName));

while (inStream.GetNextEntry())
{

     ZipEntry entry = inStream.GetNextEntry();
     //write out your entry's filename
}
6 голосов
/ 04 января 2009

Ick - этот код, использующий среду выполнения J #, отвратителен! И я не согласен с тем, что это лучший способ - J # больше не поддерживается. И это ОГРОМНОЕ время выполнения, если вам нужна только поддержка ZIP.

Как насчет этого - он использует DotNetZip (бесплатная лицензия MS-Public)

using (ZipFile zip = ZipFile.Read(zipfile) )
{
    bool header = true;
    foreach (ZipEntry e in zip)
    {
        if (header)
        {
            System.Console.WriteLine("Zipfile: {0}", zip.Name);
            if ((zip.Comment != null) && (zip.Comment != ""))
                System.Console.WriteLine("Comment: {0}", zip.Comment);

            System.Console.WriteLine("\n{1,-22} {2,9}  {3,5}   {4,9}  {5,3} {6,8} {0}",
                                     "Filename", "Modified", "Size", "Ratio", "Packed", "pw?", "CRC");
            System.Console.WriteLine(new System.String('-', 80));
            header = false;
        }

        System.Console.WriteLine("{1,-22} {2,9} {3,5:F0}%   {4,9}  {5,3} {6:X8} {0}",
                                 e.FileName,
                                 e.LastModified.ToString("yyyy-MM-dd HH:mm:ss"),
                                 e.UncompressedSize,
                                 e.CompressionRatio,
                                 e.CompressedSize,
                                 (e.UsesEncryption) ? "Y" : "N",
                                 e.Crc32);

        if ((e.Comment != null) && (e.Comment != ""))
            System.Console.WriteLine("  Comment: {0}", e.Comment);
    }
}
4 голосов
/ 09 апреля 2012

Если вы похожи на меня и не хотите использовать внешний компонент, вот код, который я разработал вчера вечером с использованием класса .NET ZipPackage.

var zipFilePath = "c:\\myfile.zip";
var tempFolderPath = "c:\\unzipped";

using (Package package = ZipPackage.Open(zipFilePath, FileMode.Open, FileAccess.Read))
{
    foreach (PackagePart part in package.GetParts())
    {
        var target = Path.GetFullPath(Path.Combine(tempFolderPath, part.Uri.OriginalString.TrimStart('/')));
        var targetDir = target.Remove(target.LastIndexOf('\\'));

        if (!Directory.Exists(targetDir))
            Directory.CreateDirectory(targetDir);

        using (Stream source = part.GetStream(FileMode.Open, FileAccess.Read))
        {
            source.CopyTo(File.OpenWrite(target));
        }
    }
}

На что обратить внимание:

  • В архиве ZIP ДОЛЖЕН быть файл [Content_Types] .xml в корневом каталоге. Это не было проблемой для моих требований, так как я буду контролировать архивирование любых ZIP-файлов, которые извлекаются с помощью этого кода. Для получения дополнительной информации о файле [Content_Types] .xml см. Новый стандарт для упаковки ваших данных Ниже приведен пример файла, приведенного ниже на рисунке 13 статьи.

  • Этот код использует метод Stream.CopyTo в .NET 4.0

4 голосов
/ 21 ноября 2008

Я здесь относительно новичок, так что, возможно, я не понимаю, что происходит. :-) В настоящее время в этой теме есть 4 ответа, где два лучших ответа были отклонены. (Pearcewg и cxfx) Статья, на которую указывает Pearcewg, важна, потому что она проясняет некоторые проблемы с лицензированием SharpZipLib. Недавно мы оценили несколько библиотек сжатия .Net и обнаружили, что DotNetZip в настоящее время является лучшей альтернативой.

Очень краткое резюме:

  • System.IO.Packaging значительно медленнее, чем DotNetZip.

  • SharpZipLib - GPL - см. Статью.

Итак, для начала я проголосовал за эти два ответа.

Ким.

0 голосов
/ 21 ноября 2008

Лучшим способом является использование встроенной в .NET функции J # zip, как показано в MSDN: http://msdn.microsoft.com/en-us/magazine/cc164129.aspx. По этой ссылке приведен полный рабочий пример чтения и записи приложения в zip-файлы. Для конкретного примера перечисления содержимого zip-файла (в данном случае пакета приложения Silverlight .xap) код может выглядеть следующим образом:


ZipFile package = new ZipFile(packagePath);
java.util.Enumeration entries = package.entries();
//We have to use Java enumerators because we
//use java.util.zip for reading the .zip files
while ( entries.hasMoreElements() )
{
    ZipEntry entry = (ZipEntry) entries.nextElement();

    if (!entry.isDirectory())
    {
        string name = entry.getName();
        Console.WriteLine("File: " + name + ", size: " + entry.getSize() + ", compressed size: " + entry.getCompressedSize());
    }
    else
    {
        // Handle directories...
    }                        
}

У Айдсмана был правильный указатель, но есть проблем . В частности, вы можете столкнуться с проблемами при открытии zip-файлов, но это правильное решение, если вы собираетесь только создавать пакеты. ZipPackage реализует абстрактный класс Package и позволяет манипулировать zip-файлами. Вот пример того, как это сделать в MSDN: http://msdn.microsoft.com/en-us/library/ms771414.aspx. Примерно код будет выглядеть так:

             string packageRelationshipType = @"http://schemas.microsoft.com/opc/2006/sample/document";
            string resourceRelationshipType = @"http://schemas.microsoft.com/opc/2006/sample/required-resource";
            // Open the Package.
            // ('using' statement insures that 'package' is
            //  closed and disposed when it goes out of scope.)
            foreach (string packagePath in downloadedFiles)
            {
                Logger.Warning("Analyzing " + packagePath);
                using (Package package = Package.Open(packagePath, FileMode.Open, FileAccess.Read))
                {
                    Logger.OutPut("package opened");
                    PackagePart documentPart = null;
                    PackagePart resourcePart = null;

                    // Get the Package Relationships and look for
                    //   the Document part based on the RelationshipType
                    Uri uriDocumentTarget = null;
                    foreach (PackageRelationship relationship in
                        package.GetRelationshipsByType(packageRelationshipType))
                    {
                        // Resolve the Relationship Target Uri
                        //   so the Document Part can be retrieved.
                        uriDocumentTarget = PackUriHelper.ResolvePartUri(
                            new Uri("/", UriKind.Relative), relationship.TargetUri);

                        // Open the Document Part, write the contents to a file.
                        documentPart = package.GetPart(uriDocumentTarget);
                        //ExtractPart(documentPart, targetDirectory);
                        string stringPart = documentPart.Uri.ToString().TrimStart('/');
                        Logger.OutPut("  Got: " + stringPart);
                    }

                    // Get the Document part's Relationships,
                    //   and look for required resources.
                    Uri uriResourceTarget = null;
                    foreach (PackageRelationship relationship in
                        documentPart.GetRelationshipsByType(
                                                resourceRelationshipType))
                    {
                        // Resolve the Relationship Target Uri
                        //   so the Resource Part can be retrieved.
                        uriResourceTarget = PackUriHelper.ResolvePartUri(
                            documentPart.Uri, relationship.TargetUri);

                        // Open the Resource Part and write the contents to a file.
                        resourcePart = package.GetPart(uriResourceTarget);

                        //ExtractPart(resourcePart, targetDirectory);
                        string stringPart = resourcePart.Uri.ToString().TrimStart('/');
                        Logger.OutPut("  Got: " + stringPart);
                    }

                }
            }

Лучше всего использовать J #, как показано в MSDN: http://msdn.microsoft.com/en-us/magazine/cc164129.aspx

В этой статье есть указатели на другие библиотеки c # .zip с разными лицензиями, например SharpNetZip и DotNetZip: как читать файлы из несжатого zip-файла в c #? . Они могут быть неподходящими из-за лицензионных требований.

...