以编程方式创建普通的zip文件

39 .net c# compression zip winforms

我已经看过很多关于如何在c#中压缩单个文件的教程.但我需要能够创建一个普通的*.zip文件,而不仅仅是一个文件..NET中有什么可以做到的吗?你会建议什么(记住我是在严格的规则下,不能使用其他库)

谢谢

Dan*_*nny 64

对于遇到这个问题的其他人来说,只是对此进行更新.

从.NET 4.5开始,您可以使用System.IO.Compression压缩文件压缩目录.您必须添加System.IO.Compression.FileSystem作为参考,因为默认情况下未引用它.然后你可以写:

System.IO.Compression.ZipFile.CreateFromDirectory(dirPath, zipFile);
Run Code Online (Sandbox Code Playgroud)

唯一可能的问题是此程序集不适用于Windows应用商店应用程序.


and*_*rsh 31

您现在可以使用.NET 4.5中提供的ZipArchive类(System.IO.Compression.ZipArchive)

示例:生成PDF文件的zip

using (var fileStream = new FileStream(@"C:\temp\temp.zip", FileMode.CreateNew))
{
    using (var archive = new ZipArchive(fileStream, ZipArchiveMode.Create, true))
    {
        foreach (var creditNumber in creditNumbers)
        {
            var pdfBytes = GeneratePdf(creditNumber);
            var fileName = "credit_" + creditNumber + ".pdf";
            var zipArchiveEntry = archive.CreateEntry(fileName, CompressionLevel.Fastest);
            using (var zipStream = zipArchiveEntry.Open())
                zipStream.Write(pdfBytes, 0, pdfBytes.Length);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Guy*_*y L 22

我的2美分:

    using (ZipArchive archive = ZipFile.Open(zFile, ZipArchiveMode.Create))
    {
        foreach (var fPath in filePaths)
        {
            archive.CreateEntryFromFile(fPath,Path.GetFileName(fPath));
        }
    }
Run Code Online (Sandbox Code Playgroud)

所以Zip文件可以直接从files/dirs创建.

  • ZipFile和ZipArchive来自程序集System.IO.Compression.FileSystem和System.IO.Compression (3认同)
  • 此库仅可从.NET framework 4.5获得 (3认同)

stu*_*rtd 20

编辑:如果您使用.Net 4.5或更高版本,则内置于框架中

对于早期版本或更多控件,您可以使用Windows的shell函数,如Gerald Gibson Jr在CodeProject上所述.

我已经复制了下面的文章文本(原始许可证:公共领域)

使用Windows Shell API和C压缩Zip文件

在此输入图像描述

介绍

这是我写的关于解压缩Zip文件的后续文章.使用此代码,您可以使用C#中的Windows Shell API压缩Zip文件,而无需显示上面显示的"复制进度"窗口.通常,当您使用Shell API压缩Zip文件时,即使您设置选项告诉Windows不显示它,它也会显示"复制进度"窗口.为了解决这个问题,您将Shell API代码移动到单独的可执行文件中,然后使用.NET Process类启动该可执行文件,确保将进程窗口样式设置为"Hidden".

背景

曾经需要压缩Zip文件并且需要比许多免费压缩库更好的Zip吗?即你需要压缩文件夹和子文件夹以及文件.Windows Zipping可以压缩的不仅仅是单个文件.您只需要一种以编程方式让Windows静默压缩这些Zip文件的方法.当然,您可以在其中一个商业Zip组件上花费300美元,但如果您只需要压缩文件夹层次结构就很难免费.

使用代码

以下代码显示如何使用Windows Shell API压缩Zip文件.首先,您创建一个空的Zip文件.为此,请创建一个正确构造的字节数组,然后将该数组保存为扩展名为".zip"的文件.我怎么知道要放入数组的字节数?好吧,我只是使用Windows来创建一个Zip文件,里面压缩了一个文件.然后我用Windows打开了Zip并删除了压缩文件.这给我留下了一个空的Zip.接下来,我在十六进制编辑器(Visual Studio)中打开空Zip文件,查看十六进制字节值,并使用Windows Calc将它们转换为十进制,并将这些十进制值复制到我的字节数组代码中.源文件夹指向要压缩的文件夹.目标文件夹指向刚刚创建的空Zip文件.这个代码将压缩Zip文件,但它也将显示"复制进度"窗口.要使此代码有效,您还需要设置对COM库的引用.在"引用"窗口中,转到"COM"选项卡,然后选择标记为"Microsoft Shell控件和自动化"的库.

//Create an empty zip file
byte[] emptyzip = new byte[]{80,75,5,6,0,0,0,0,0, 
                  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

FileStream fs = File.Create(args[1]);
fs.Write(emptyzip, 0, emptyzip.Length);
fs.Flush();
fs.Close();
fs = null;

//Copy a folder and its contents into the newly created zip file
Shell32.ShellClass sc = new Shell32.ShellClass();
Shell32.Folder SrcFlder = sc.NameSpace(args[0]);
Shell32.Folder DestFlder = sc.NameSpace(args[1]); 
Shell32.FolderItems items = SrcFlder.Items();
DestFlder.CopyHere(items, 20);

//Ziping a file using the Windows Shell API 
//creates another thread where the zipping is executed.
//This means that it is possible that this console app 
//would end before the zipping thread 
//starts to execute which would cause the zip to never 
//occur and you will end up with just
//an empty zip file. So wait a second and give 
//the zipping thread time to get started
System.Threading.Thread.Sleep(1000);
Run Code Online (Sandbox Code Playgroud)

本文附带的示例解决方案显示了如何将此代码放入控制台应用程序,然后启动此控制台应用程序以压缩Zip而不显示"复制进度"窗口.

下面的代码显示了一个按钮单击事件处理程序,其中包含用于启动控制台应用程序的代码,以便在压缩期间没有UI:

private void btnUnzip_Click(object sender, System.EventArgs e)
{
    //Test to see if the user entered a zip file name
    if(txtZipFileName.Text.Trim() == "")
    {
        MessageBox.Show("You must enter what" + 
               " you want the name of the zip file to be");
        //Change the background color to cue the user to what needs fixed
        txtZipFileName.BackColor = Color.Yellow;
        return;
    }
    else
    {
        //Reset the background color
        txtZipFileName.BackColor = Color.White;
    }

    //Launch the zip.exe console app to do the actual zipping
    System.Diagnostics.ProcessStartInfo i =
        new System.Diagnostics.ProcessStartInfo(
        AppDomain.CurrentDomain.BaseDirectory + "zip.exe");
    i.CreateNoWindow = true;
    string args = "";


    if(txtSource.Text.IndexOf(" ") != -1)
    {
        //we got a space in the path so wrap it in double qoutes
        args += "\"" + txtSource.Text + "\"";
    }
    else
    {
        args += txtSource.Text;
    }

    string dest = txtDestination.Text;

    if(dest.EndsWith(@"\") == false)
    {
        dest += @"\";
    }

    //Make sure the zip file name ends with a zip extension
    if(txtZipFileName.Text.ToUpper().EndsWith(".ZIP") == false)
    {
        txtZipFileName.Text += ".zip";
    }

    dest += txtZipFileName.Text;

    if(dest.IndexOf(" ") != -1)
    {
        //we got a space in the path so wrap it in double qoutes
        args += " " + "\"" + dest + "\"";
    }
    else
    {
        args += " " + dest;
    }

    i.Arguments = args;


    //Mark the process window as hidden so 
    //that the progress copy window doesn't show
    i.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;    
    System.Diagnostics.Process p = System.Diagnostics.Process.Start(i);
    p.WaitForExit();
    MessageBox.Show("Complete");
}
Run Code Online (Sandbox Code Playgroud)

  • 从.NET 4.5开始,您可以使用`System.IO.Compression.ZipFile`来完成此任务.有关详细信息,请参阅[此答案](http://stackoverflow.com/a/19613011/444991) (4认同)
  • 谢谢@Stuart.非常感激! (2认同)

Jak*_*ake 20

以下是您可能会考虑的一些资源: 在.NET中创建Zip存档(没有像SharpZipLib这样的外部库)

使用System.IO.Packaging压缩您的流

我的建议和偏好是使用system.io.packacking.这可以减少您的依赖关系(只是框架).Jgalloway的帖子(第一个参考)提供了一个将两个文件添加到zip文件的好例子.是的,它更冗长,但您可以轻松创建一个外观(在某种程度上,他的AddFileToZip可以做到这一点).

HTH


cod*_*nix 6

您可以尝试使用SharpZipLib.是开源,平台独立的纯c#代码.


gyu*_*isc 5

.NET 具有用于压缩System.IO.Compression命名空间中的文件的内置功能。使用它,您不必将额外的库作为依赖项。此功能可从 .NET 2.0 获得。

这是从我链接的 MSDN 页面进行压缩的方法:

    public static void Compress(FileInfo fi)
    {
        // Get the stream of the source file.
        using (FileStream inFile = fi.OpenRead())
        {
            // Prevent compressing hidden and already compressed files.
            if ((File.GetAttributes(fi.FullName) & FileAttributes.Hidden)
                    != FileAttributes.Hidden & fi.Extension != ".gz")
            {
                // Create the compressed file.
                using (FileStream outFile = File.Create(fi.FullName + ".gz"))
                {
                    using (GZipStream Compress = new GZipStream(outFile,
                            CompressionMode.Compress))
                    {
                        // Copy the source file into the compression stream.
                        byte[] buffer = new byte[4096];
                        int numRead;
                        while ((numRead = inFile.Read(buffer, 0, buffer.Length)) != 0)
                        {
                            Compress.Write(buffer, 0, numRead);
                        }
                        Console.WriteLine("Compressed {0} from {1} to {2} bytes.",
                            fi.Name, fi.Length.ToString(), outFile.Length.ToString());
                    }
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)