65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 压缩文件和/或文件夹

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.82/5 (19投票s)

2009年7月8日

CPOL

2分钟阅读

viewsIcon

248047

downloadIcon

8950

如何使用 C# 压缩文件和/或文件夹

引言

在您开发 C# 应用程序时,您可能需要执行一些特定的或特殊的操作,例如压缩文件以下载,或发送带有压缩文件附件的电子邮件,或执行备份。 本文为您提供了一个压缩文件和/或文件夹的解决方案,尊重文件夹的整个树结构,而无需购买第三方解决方案。

背景

C# 默认使用 GZip,它实际上不是一个 zip 文件(它是不同的)。 因此,寻找解决方案时,您有两种选择

  • 使用第三方解决方案
  • 自己动手

虽然有免费的第三方解决方案,例如...

...您可能会发现自己想自己动手,无需这些库,而仅使用 .NET 标准库。 本文展示了方法。 如果您尝试仅在 C# 上查找必要的代码,您会发现自己迷失了方向。 C# 只有 GZip 的代码,这不是 zip。 经过大量的 Google 搜索后,我找到了一个解决方案,它使用了 C# 和 J# 的混合。 J# 提供了专门用于压缩的库(java.util.zip)。 但您可能会对“如何在 C# 上使用 J#!”感到困惑。 简单来说,只需添加对 vjslib.dll 库的引用(见下图),并导入命名空间以执行所需的 zip 操作。

add_reference.PNG - Click to enlarge image

Using the Code

该解决方案非常简单,但它要求您选择正确的方法和特定参数。 在我的示例中,您有一个简单的 Web 应用程序,带有一个按钮和一个标签来显示此过程的结果。 当您按下按钮时,会调用 C# 和 J# 的混合来压缩文件夹。 当 .NET 编译项目时,它会将此混合组装成一个单独的应用程序。(请注意,您必须在您的 Web 服务器上安装 J# 库安装程序,否则您将无法使其工作。)

using java.io;
using java.util.zip;
using System.IO;
using System.Text;
protected void btnZip_Click(object sender, EventArgs e)
    {
        StringBuilder sb = new StringBuilder(); 	//  Builder to save report
        string ZipFileName = String.Format(@"C:\ZippedFolders\({0}).MyZip.zip",
		DateTime.Now.ToString("yyyyMMdd")); 	//  Zip Destiny File Name
        string theDirectory = @"C:\FolderToZip";    	//  Folder to zip

        try
        {
            sb.Append(String.Format("Directory To Zip: {0}.<br/>", theDirectory));
            sb.Append(String.Format("Zip file: {0}.<br/>", ZipFileName));

            string[] allFiles = Directory.GetFiles(theDirectory, "*.*",
		SearchOption.AllDirectories);   	// Get all files from
						// the folder to zip

            if (System.IO.File.Exists(ZipFileName)) 	//  Small piece of code
					// to delete zip file if it already exists
            {
                System.IO.File.Delete(ZipFileName);
                sb.Append(String.Format
		("Deleted old Zip file: {0}.<br/>", ZipFileName));
            }

            //  J# code to zip

            FileOutputStream fos = new FileOutputStream(ZipFileName); //  J# output
							      // stream (Zip File)
            ZipOutputStream zos = new ZipOutputStream(fos);           //  J# output zip
            zos.setLevel(9);    //  Set the level of compression.
				// It may be a value between 0 and 9

            /*
                Add each file from folder to zip, to zip file.
                This way, the tree of the folder to zip will be
                reflected on the zip file
            */

            for (int i = 0; i < allFiles.Length; i++ )
            {
                string sourceFile = allFiles[i];

                FileInputStream fis = new FileInputStream(sourceFile);  //  J# input
							//stream to fill zip file
                /*
                    Add the entry to the zip file (The Replace will remove the full path
                    Ex.: file C:\FolderToZip\Files\Tmp\myFile.xml,
		  will be written as Files\Tmp\myFile.xml on the zip file
                    If this code was not written, it would generate the
		  whole tree since the beginning of the FolderToZip
                    This way the zip file begins directly at the contents
		  of C:\FolderToZip
                */

                ZipEntry ze = new ZipEntry(sourceFile.Replace(theDirectory + @"\", ""));
                zos.putNextEntry(ze);

                sbyte[] buffer = new sbyte[1024];
                int len;

                while ((len = fis.read(buffer)) >= 0)
                {
                    zos.write(buffer, 0, len);  //  Write buffer to Zip File
                }

                fis.close();    //  Close input Stream
            }

            //  Close outputs
            zos.closeEntry();
            zos.close();
            fos.close();

            sb.Append(String.Format("Folder {0} Zipped successfully to File {1}.<br/>",
						theDirectory, ZipFileName));

        }
        catch (Exception eX)
        {
            sb.Append(String.Format("Error zipping folder {0}. Details: {1}.
		Stack Trace: {2}.<br/>", theDirectory, eX.Message, eX.StackTrace));
        }

        lbReport.Text = sb.ToString();  //  Show result/report
    }

要压缩的物理文件夹

folder_to_zip.PNG

按下按钮后 Web 应用程序的结果

result.PNG

以及压缩文件夹中的压缩文件

zipped_folders.PNG

关注点

关于此解决方案,最有趣的一点是您可以在同一代码中使用 C# 和 J# 库,并将它们一起编译以完成一个解决方案。 C# 本身及其标准库不提供 zip 方法。 但是,J# 提供了,然而您正在使用 C# 编程。 那么,为什么不将它们混合在同一个解决方案中呢?!

另一个有趣的观点是,网络上有几个解决方案,它们都是可以下载的库,但您必须为其许可证付费。 这是一个仅使用 .NET 库的解决方案,不涉及任何第三方解决方案。

历史

在收到一些评论后,生成了一个新版本,调整了图像大小,为代码添加了注释并解释了此解决方案。

© . All rights reserved.