如何压缩文件

19

我想在C#中压缩文件和目录。我在互联网上找到了一些解决方案,但它们非常复杂,我无法在我的项目中运行它们。是否有人可以提供一个清晰有效的解决方案?


你的项目为什么不能运行它们? - BugFinder
1
可能是重复的问题:如何以编程方式将目录压缩为zip文件 - ken2k
@BugFinder 例如,我在这里找到了一个解决方案http://cheeso.members.winisp.net/DotNetZipHelp/html/ca1725fb-8fbc-c786-feb9-672fabd9140d.htm,但我无法在我的项目中描述“ZipFile”。尽管我已经添加了“using System.IO.Compression;”库,但错误并没有消失。关于ZipFile有很多代码。这可能是关于C#的问题,我能在C#中使用这个类吗? - eponymous
@aprogrammer,请参考https://dev59.com/yXE95IYBdhLWcg3wm_It。 - Romil Kumar Jain
@BugFinder 这是一个C#代码链接:“http://cheeso.members.winisp.net/DotNetZipHelp/html/ca1725fb-8fbc-c786-feb9-672fabd9140d.htm”,但它只能获取第一个子文件夹。我使用了这行代码“zip.AddDirectory(path);”代替了代码块的前两行,这样代码就可以获取所有子文件夹了。我还在我的代码中添加了“Ionic.Zip;”dll。感谢你们的帮助。 - eponymous
显示剩余11条评论
10个回答

25

您可以在System.IO.Compression命名空间中使用GZipStream

.NET 2.0。

public static void CompressFile(string path)
{
    FileStream sourceFile = File.OpenRead(path);
    FileStream destinationFile = File.Create(path + ".gz");

    byte[] buffer = new byte[sourceFile.Length];
    sourceFile.Read(buffer, 0, buffer.Length);

    using (GZipStream output = new GZipStream(destinationFile,
        CompressionMode.Compress))
    {
        Console.WriteLine("Compressing {0} to {1}.", sourceFile.Name,
            destinationFile.Name, false);

        output.Write(buffer, 0, buffer.Length);
    }

    // Close the files.
    sourceFile.Close();
    destinationFile.Close();
}

.NET 4

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.
                    inFile.CopyTo(Compress);

                        Console.WriteLine("Compressed {0} from {1} to {2} bytes.",
                            fi.Name, fi.Length.ToString(), outFile.Length.ToString());
                    }
                }
            }
        }
    }

http://msdn.microsoft.com/en-us/library/ms404280.aspx


@Romil - 不,这个命名空间在2.0版本中是可用的,我已经检查过了。你也可以在此链接找到证明:http://msdn.microsoft.com/en-us/library/ms404280(v=vs.80).aspx - Darren
我尝试使用这段代码片段,但是我遇到了关于访问文件路径的问题。我收到了一个错误信息?无法访问文件路径的原因是什么? - eponymous
错误 ---> 拒绝访问"c:/Temp"路径。这可能是什么原因? - eponymous
@Selen - 也许你的账户没有访问该文件夹/文件的权限。这个解决方案有帮助吗?如果有,请将其标记为答案。 - Darren
离题:在你的if语句中,应该使用等于运算符&&而不是二进制&。 - Bernhard
显示剩余3条评论

21

我添加了这个答案是因为我发现一个比现有的任何答案都更简单的方法:

  1. 在您的解决方案中安装DotNetZip DLL(最简单的方法是从nuget安装
  2. 添加对该DLL的引用。
  3. 通过添加以下代码导入命名空间:using Ionic.Zip;
  4. 压缩您的文件

代码:

using (ZipFile zip = new ZipFile())
{
    zip.AddFile("C:\test\test.txt");
    zip.AddFile("C:\test\test2.txt");
    zip.Save("C:\output.zip");
}

如果你不想在zip文件中镜像原始文件夹结构,则可以查看AddFile()和AddFolder()等函数的覆盖选项。


同意,如果不是最容易的话,那也是最容易的之一。 - AMissico
1
DotNetZip似乎已经多年没有维护了,并且在压缩某些大文件时存在一个错误:https://dotnetzip.codeplex.com/workitem/14087我发现使用一个不能可靠地将文件添加到存档中的zip库太可怕了。有人能证实DotNetZip存在问题吗? - Peter Huber
1
@PeterHuber 是的,它确实有那个 bug,但是修复方法在你发布的链接中。 - NickG

3

对于.NET Framework 4.5,这是我找到的最清晰的例子:

using System;
using System.IO;
using System.IO.Compression;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            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 的引用。
来自:https://learn.microsoft.com/zh-cn/dotnet/standard/io/how-to-compress-and-extract-files

2

4
.NET 2.0中没有像用户所要求的那样可用。 - Arnaud F.

1

只需使用以下代码压缩文件。

       public void Compressfile()
        {
             string fileName = "Text.txt";
             string sourcePath = @"C:\SMSDBBACKUP";
             DirectoryInfo di = new DirectoryInfo(sourcePath);
             foreach (FileInfo fi in di.GetFiles())
             {
                 //for specific file 
                 if (fi.ToString() == fileName)
                 {
                     Compress(fi);
                 }
             } 
        }

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.
                            inFile.CopyTo(Compress);

                            Console.WriteLine("Compressed {0} from {1} to {2} bytes.",
                                fi.Name, fi.Length.ToString(), outFile.Length.ToString());
                        }
                    }
                }
            }
        }

    }

1
你可以使用ms-dos命令行程序compact.exe。在cmd中查看compact.exe参数,并使用.NET方法Process.Start()启动此进程。

1
使用DotNetZip http://dotnetzip.codeplex.com/,ZipFile类上有一个AddDirectory()方法可以实现您所需的功能。
using (var zip = new Ionic.Zip.ZipFile())
{
    zip.AddDirectory("DirectoryOnDisk", "rootInZipFile");
    zip.Save("MyFile.zip");
}

祝您继续成功...


1

@aprogrammer 不用谢。很抱歉我没有发布一些代码,因为我不确定我在哪里有它,而且现在时间也不多。 - CarlosJ

0

从MSDN获取的源代码,兼容.Net 2.0及以上版本

public static void CompressFile(string path)
        {
            FileStream sourceFile = File.OpenRead(path);
            FileStream destinationFile = File.Create(path + ".gz");

            byte[] buffer = new byte[sourceFile.Length];
        sourceFile.Read(buffer, 0, buffer.Length);

        using (GZipStream output = new GZipStream(destinationFile,
            CompressionMode.Compress))
        {
            Console.WriteLine("Compressing {0} to {1}.", sourceFile.Name,
                destinationFile.Name, false);

            output.Write(buffer, 0, buffer.Length);
        }

        // Close the files.
        sourceFile.Close();
        destinationFile.Close();
    }  

我尝试使用这段代码片段,但是我遇到了关于访问文件路径的问题。我收到了一个错误信息?无法访问文件路径的原因是什么? - eponymous
尝试在D盘(非操作系统驱动器)上创建文件。在Windows 7中,您应该会遇到访问问题,请在try...catch中捕获异常并进行验证。 - Romil Kumar Jain

0

谢谢@Arnaud F. 我看到了,但是我的程序不认识ZipFile。我该如何在我的程序中描述它? - eponymous

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接