31

如何在 C# 中列出压缩文件夹的内容?例如,如何知道压缩文件夹中包含多少项目,它们的名称是什么?

4

8 回答 8

35

.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 中。不需要任何 3rd 方库。

string zipPath = @"c:\example\start.zip";
using (ZipArchive archive = ZipFile.OpenRead(zipPath))
{
    foreach (ZipArchiveEntry entry in archive.Entries)
    {
        Console.WriteLine(entry.FullName);
    }
} 
于 2014-02-13T23:28:30.037 回答
34

DotNetZip - .NET 语言中的 Zip 文件操作

DotNetZip 是一个小型、易于使用的类库,用于处理 .zip 文件。它可以使用 VB.NET、C#、任何 .NET 语言编写的 .NET 应用程序轻松创建、读取和更新 zip 文件。

读取 zip 的示例代码:

using (var zip = ZipFile.Read(PathToZipFolder))
{
    int totalEntries = zip.Entries.Count; 
    foreach (ZipEntry e in zip.Entries)
    {
        e.FileName ...
        e.CompressedSize ...
        e.LastModified...
    }
}
于 2008-11-21T03:53:47.070 回答
21

如果您使用的是 .Net Framework 3.0 或更高版本,请查看System.IO.Packaging 命名空间。这将消除您对外部库的依赖。

具体检查ZipPackage 类

于 2008-11-21T04:03:09.843 回答
12

检查SharpZipLib

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

while (inStream.GetNextEntry())
{

     ZipEntry entry = inStream.GetNextEntry();
     //write out your entry's filename
}
于 2008-11-21T03:49:16.487 回答
6

Ick - 使用 J# 运行时的代码太可怕了!而且我不同意这是最好的方法 - J# 现在不支持了。它是一个巨大的运行时,如果你想要的只是 ZIP 支持。

这个怎么样 - 它使用DotNetZip(免费,MS-公共许可证)

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);
    }
}
于 2009-01-04T04:24:15.743 回答
4

我在这里相对较新,所以也许我不明白发生了什么。:-) 此线程目前有 4 个答案,其中两个最佳答案已被否决。(Percewg 的和 cxfx 的) pearcewg 指出的文章很重要,因为它阐明了 SharpZipLib 的一些许可问题。我们最近评估了几个 .Net 压缩库,发现 DotNetZip 是目前最好的替代方案。

非常简短的总结:

  • System.IO.Packaging 比 DotNetZip 慢得多。

  • SharpZipLib 是 GPL - 见文章。

因此,对于初学者来说,我对这两个答案投了赞成票。

金。

于 2008-11-21T04:58:11.387 回答
4

如果您像我一样不想使用外部组件,这里是我昨晚使用 .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 文件的更多信息,请参阅:A New Standard For Packaging Your Data 在文章的图 13 下方有一个示例文件。

  • 此代码使用 .NET 4.0 中的 Stream.CopyTo 方法

于 2012-04-09T11:34:07.173 回答
0

最好的方法是使用 .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 文件的问题,但如果您打算创建 pacakges,这是一个有效的解决方案。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:如何在 c# 中从未压缩的 zip 中读取文件?. 由于许可证要求,它们可能不适合。

于 2008-11-21T17:29:22.917 回答