【问题标题】:Zip folder in C#C#中的压缩文件夹
【发布时间】:2010-10-28 16:27:23
【问题描述】:

什么是如何在 C# 中压缩文件夹的示例(简单代码)?


更新:

我没有看到命名空间ICSharpCode。我下载了ICSharpCode.SharpZipLib.dll,但我不知道在哪里复制那个 DLL 文件。我需要做什么才能看到这个命名空间?

你是否有压缩文件夹的 MSDN 示例的链接,因为我阅读了所有 MSDN 但我找不到任何东西。


好的,但我需要下一个信息。

我应该在哪里复制 ICSharpCode.SharpZipLib.dll 以在 Visual Studio 中查看该命名空间?

【问题讨论】:

  • (将“回复”的后续内容移至问题中)
  • 项目 -> 添加引用 -> 选择库

标签: c# zip directory archive compression


【解决方案1】:

BCL 中没有什么可以为您执行此操作,但有两个用于 .NET 的出色库确实支持该功能。

两个我都用过,可以说两个都非常齐全,API设计的很好,所以主要看个人喜好。

我不确定他们是否明确支持添加文件夹,而不仅仅是将单个文件添加到 zip 文件中,但创建递归迭代目录及其子目录的内容应该很容易使用DirectoryInfoFileInfo 类。

【讨论】:

  • DotNetZip 支持通过 ZipFile.AddDirectory() 方法将目录添加到 zip 文件。它通过目录递归。
  • 您可以使用 SharpZipLib 添加文件夹,只需在 zip 条目名称中添加文件夹名称和斜线(不记得是向前还是向后)。
  • SharpZipLib 拥有 GPL 许可证:weblogs.asp.net/jgalloway/archive/2007/10/25/…
  • DotNetZip 的 +1。我工作的组织广泛使用它,它非常适合各种任务。
【解决方案2】:

MSDN 上有一篇文章,其中有一个示例应用程序,用于纯粹用 C# 压缩和解压缩文件和文件夹。很长一段时间以来,我一直在成功地使用其中的一些课程。如果您需要了解这类事情,代码是根据 Microsoft Permissive License 发布的。

编辑:感谢 Cheeso 指出我有点落后于时代。我指出的 MSDN 示例实际上是使用 DotNetZip 并且现在功能非常齐全。根据我对以前版本的经验,我很乐意推荐它。

SharpZipLib 也是一个相当成熟的库,受到人们的高度评价,并且在 GPL 许可下可用。这实际上取决于您的压缩需求以及您如何查看它们的许可条款。

丰富

【讨论】:

  • MSDN 上的示例代码使用 DotNetZip,这是一个支持压缩级别和加密(包括 AES 加密)的免费 zip 库,尽管您引用的特定示例没有显示这一点。该库生成“正确”的 zip 文件。
  • 感谢您提及。我仍在使用几年前的原始版本,它只是一个独立的代码示例,所以看起来他们已经做了很多工作。
  • 我向 Cheeso 道歉,如果不是 DotNetZip 库的作者,您似乎就是管理员!事实证明,它对我非常有用,即使是在我第一次遇到它时的早期形式。 :)
  • 根据 Cheeso 的评论编辑。
【解决方案3】:

来自DotNetZip 帮助文件,http://dotnetzip.codeplex.com/releases/

using (ZipFile zip = new ZipFile())
{
   zip.UseUnicodeAsNecessary= true;  // utf-8
   zip.AddDirectory(@"MyDocuments\ProjectX");
   zip.Comment = "This zip was created at " + System.DateTime.Now.ToString("G") ; 
   zip.Save(pathToSaveZipFile);
}

【讨论】:

  • @JohnB 这已经被弃用了
  • 这是添加目录的内容。我想在 zip 中包含 Main 目录,我希望 ProhjectX 也包含在它的内容中?
【解决方案4】:

"Where should I copy ICSharpCode.SharpZipLib.dll to see that namespace in Visual Studio?"

您需要在项目中添加 dll 文件作为参考。右键单击解决方案资源管理器中的引用->添加引用->浏览,然后选择 dll。

最后,您需要将它作为 using 语句添加到您想要使用它的任何文件中。

【讨论】:

    【解决方案5】:

    以下代码使用第三方ZIP component from Rebex

    // add content of the local directory C:\Data\  
    // to the root directory in the ZIP archive
    // (ZIP archive C:\archive.zip doesn't have to exist) 
    Rebex.IO.Compression.ZipArchive.Add(@"C:\archive.zip", @"C:\Data\*", "");
    

    或者如果您想添加更多文件夹而无需多次打开和关闭存档:

    using Rebex.IO.Compression;
    ...
    
    // open the ZIP archive from an existing file 
    ZipArchive zip = new ZipArchive(@"C:\archive.zip", ArchiveOpenMode.OpenOrCreate);
    
    // add first folder
    zip.Add(@"c:\first\folder\*","\first\folder");
    
    // add second folder
    zip.Add(@"c:\second\folder\*","\second\folder");
    
    // close the archive 
    zip.Close(ArchiveSaveAction.Auto);
    

    你可以download the ZIP component here

    使用免费的、获得 LGPL 许可的 SharpZipLib 是一种常见的替代方法。

    免责声明:我为 Rebex 工作

    【讨论】:

      【解决方案6】:

      System.IO.Packaging 命名空间中有一个 ZipPackage 类,它内置于 .NET 3、3.5 和 4.0 中。

      http://msdn.microsoft.com/en-us/library/system.io.packaging.zippackage.aspx

      这是一个如何使用它的示例。 http://www.codeproject.com/KB/files/ZipUnZipTool.aspx?display=Print

      【讨论】:

        【解决方案7】:

        这个答案随着 .NET 4.5 而改变。创建一个压缩文件becomes incredibly easy。不需要第三方库。

        string startPath = @"c:\example\start";
        string zipPath = @"c:\example\result.zip";
        string extractPath = @"c:\example\extract";
        
        ZipFile.CreateFromDirectory(startPath, zipPath);
        ZipFile.ExtractToDirectory(zipPath, extractPath);
        

        【讨论】:

        • 这很好用。不要忘记添加对 System.IO.Compression.FileSystem 的引用和 System.IO.Compression 的 using 语句。
        • 我不敢相信这是多么简单。非常感谢!
        • 使用原路径和目的路径相同时出错,记得使用和原路径不同的目的路径。
        • @ThanhLD 是的,他们没有成功,所以不幸的是,您可以将 result.zip 放在文件夹中(即 startPath)......
        【解决方案8】:

        ComponentPro ZIP 可以帮助您完成这项任务。以下代码 sn -p 压缩文件夹中的文件和目录。您也可以使用通配符掩码。

        using ComponentPro.Compression;
        using ComponentPro.IO;
        
        ...
        
        // Create a new instance.
        Zip zip = new Zip();
        // Create a new zip file.
        zip.Create("test.zip");
        
        zip.Add(@"D:\Temp\Abc"); // Add entire D:\Temp\Abc folder to the archive.
        
        // Add all files and subdirectories from 'c:\test' to the archive.
        zip.AddFiles(@"c:\test");
        // Add all files and subdirectories from 'c:\my folder' to the archive.
        zip.AddFiles(@"c:\my folder", "");
        // Add all files and subdirectories from 'c:\my folder' to '22' folder within the archive.
        zip.AddFiles(@"c:\my folder2", "22");
        // Add all .dat files from 'c:\my folder' to '22' folder within the archive.
        zip.AddFiles(@"c:\my folder2", "22", "*.dat");
        // Or simply use this to add all .dat files from 'c:\my folder' to '22' folder within the archive.
        zip.AddFiles(@"c:\my folder2\*.dat", "22");
        // Add *.dat and *.exe files from 'c:\my folder' to '22' folder within the archive.
        zip.AddFiles(@"c:\my folder2\*.dat;*.exe", "22");
        
        TransferOptions opt = new TransferOptions();
        // Donot add empty directories.
        opt.CreateEmptyDirectories = false;
        zip.AddFiles(@"c:\abc", "/", opt);
        
        // Close the zip file.
        zip.Close();
        

        http://www.componentpro.com/doc/zip 有更多例子

        【讨论】:

        • FWIW,请参阅 cheated.by.safabyte.net,它显示 Component Pro 可能代表被盗软件的最新版本。 TY
        【解决方案9】:

        在 .NET 4.5 中,ZipFile.CreateFromDirectory(startPath, zipPath);方法不涵盖您希望压缩多个文件和子文件夹而不必将它们放在文件夹中的情况。当您希望解压缩将文件直接放在当前文件夹中时,这是有效的。

        这段代码对我有用:

        public static class FileExtensions
        {
            public static IEnumerable<FileSystemInfo> AllFilesAndFolders(this DirectoryInfo dir)
            {
                foreach (var f in dir.GetFiles())
                    yield return f;
                foreach (var d in dir.GetDirectories())
                {
                    yield return d;
                    foreach (var o in AllFilesAndFolders(d))
                        yield return o;
                }
            }
        }
        
        void Test()
        {
            DirectoryInfo from = new DirectoryInfo(@"C:\Test");
            using (var zipToOpen = new FileStream(@"Test.zip", FileMode.Create))
            {
                using (var archive = new ZipArchive(zipToOpen, ZipArchiveMode.Create))
                {
                    foreach (var file in from.AllFilesAndFolders().OfType<FileInfo>())
                    {
                        var relPath = file.FullName.Substring(from.FullName.Length+1);
                        ZipArchiveEntry readmeEntry = archive.CreateEntryFromFile(file.FullName, relPath);
                    }
                }
            }
        }
        

        文件夹不需要在 zip 存档中“创建”。 CreateEntryFromFile中的第二个参数“entryName”应该是一个相对路径,解压zip文件时会检测并创建相对路径的目录。

        【讨论】:

        【解决方案10】:

        使用 DotNetZip(作为 nuget 包提供):

        public void Zip(string source, string destination)
        {
            using (ZipFile zip = new ZipFile
            {
                CompressionLevel = CompressionLevel.BestCompression
            })
            {
                var files = Directory.GetFiles(source, "*",
                    SearchOption.AllDirectories).
                    Where(f => Path.GetExtension(f).
                        ToLowerInvariant() != ".zip").ToArray();
        
                foreach (var f in files)
                {
                    zip.AddFile(f, GetCleanFolderName(source, f));
                }
        
                var destinationFilename = destination;
        
                if (Directory.Exists(destination) && !destination.EndsWith(".zip"))
                {
                    destinationFilename += $"\\{new DirectoryInfo(source).Name}-{DateTime.Now:yyyy-MM-dd-HH-mm-ss-ffffff}.zip";
                }
        
                zip.Save(destinationFilename);
            }
        }
        
        private string GetCleanFolderName(string source, string filepath)
        {
            if (string.IsNullOrWhiteSpace(filepath))
            {
                return string.Empty;
            }
        
            var result = filepath.Substring(source.Length);
        
            if (result.StartsWith("\\"))
            {
                result = result.Substring(1);
            }
        
            result = result.Substring(0, result.Length - new FileInfo(filepath).Name.Length);
        
            return result;
        }
        

        用法:

        Zip(@"c:\somefolder\subfolder\source", @"c:\somefolder2\subfolder2\dest");
        

        或者

        Zip(@"c:\somefolder\subfolder\source", @"c:\somefolder2\subfolder2\dest\output.zip");
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-09-05
          • 2011-07-11
          • 2017-08-15
          • 2016-06-25
          • 2013-03-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多