C# 压缩和解压缩文件

System.IO.Compression 命名空间包含以下类来对文件和流进行压缩或解压缩。 还可以使用这些类型来读取和修改压缩文件的内容:

  • ZipFile
  • ZipArchive
  • ZipArchiveEntry
  • DeflateStream
  • GZipStream

下面的示例演示使用压缩文件可以执行的某些操作。 这些示例需要将以下 NuGet 包添加到项目中:

  • System.IO.Compression
  • System.IO.Compression.ZipFile

如果你使用的是 .NET Framework,请将对这两个库的引用添加到项目中:

  • System.IO.Compression
  • System.IO.Compression.FileSystem

示例 1:创建和提取 .zip 文件

以下示例演示如何使用 ZipFile 类创建和提取压缩的 .zip 文件。 该示例将文件夹的内容压缩为一个新的 .zip 文件,然后将该文件提取到一个新文件夹。

若要运行示例,请在程序文件夹中创建 start 文件夹,然后在其中放入要压缩的文件。

C#复制

using System;
using System.IO.Compression;

class Program
{
    static void Main(string[] args)
    {
        string startPath = @".\start";
        string zipPath = @".\result.zip";
        string extractPath = @".\extract";

        ZipFile.CreateFromDirectory(startPath, zipPath);

        ZipFile.ExtractToDirectory(zipPath, extractPath);
    }
}

示例 2:提取特定文件扩展名

以下示例循环访问现有 .zip 文件的内容并提取扩展名为 .txt 的文件。 它使用 ZipArchive 类访问 .zip 文件,使用 ZipArchiveEntry 类检查各个条目。 适用于 ExtractToFile 对象的扩展方法 ZipArchiveEntry 可以在 System.IO.Compression.ZipFileExtensions 类中使用。

若要运行示例,请将名为 result.zip 的 .zip 文件放到程序文件夹中 。 出现提示时,提供要提取到的文件夹名称。

 重要

在解压缩文件时,必须查找可以从你想要解压缩到的目录转义的恶意文件路径。 这被称为“路径遍历攻击”。 下面的示例演示如何检查恶意文件路径,并提供一种安全的解压缩方法。

C#复制

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

class Program
{
    static void Main(string[] args)
    {
        string zipPath = @".\result.zip";

        Console.WriteLine("Provide path where to extract the zip file:");
        string extractPath = Console.ReadLine();

        // Normalizes the path.
        extractPath = Path.GetFullPath(extractPath);

        // Ensures that the last character on the extraction path
        // is the directory separator char.
        // Without this, a malicious zip file could try to traverse outside of the expected
        // extraction path.
        if (!extractPath.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
            extractPath += Path.DirectorySeparatorChar;

        using (ZipArchive archive = ZipFile.OpenRead(zipPath))
        {
            foreach (ZipArchiveEntry entry in archive.Entries)
            {
                if (entry.FullName.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
                {
                    // Gets the full path to ensure that relative segments are removed.
                    string destinationPath = Path.GetFullPath(Path.Combine(extractPath, entry.FullName));

                    // Ordinal match is safest, case-sensitive volumes can be mounted within volumes that
                    // are case-insensitive.
                    if (destinationPath.StartsWith(extractPath, StringComparison.Ordinal))
                        entry.ExtractToFile(destinationPath);
                }
            }
        }
    }
}

示例 3:将新文件添加到现有 .zip 文件

以下示例使用 ZipArchive 类访问现有的 .zip 文件,然后向其添加文件。 当将其添加到现有的 .zip 文件时,会对新文件进行压缩。

C#复制

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

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            using (FileStream zipToOpen = new FileStream(@"c:\users\exampleuser\release.zip", FileMode.Open))
            {
                using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Update))
                {
                    ZipArchiveEntry readmeEntry = archive.CreateEntry("Readme.txt");
                    using (StreamWriter writer = new StreamWriter(readmeEntry.Open()))
                    {
                            writer.WriteLine("Information about this package.");
                            writer.WriteLine("========================");
                    }
                }
            }
        }
    }
}

示例 4:压缩和解压缩 .gz 文件

您也可以使用 GZipStream 和 DeflateStream 类压缩和解压缩数据。 它们使用相同的压缩算法。 可以使用许多常用工具解压缩写入 .gz 文件的 GZipStream 对象。 以下示例展示了如何使用 GZipStream 类压缩和解压缩文件目录:

C#复制

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

public class Program
{
    private static string directoryPath = @".\temp";
    public static void Main()
    {
        DirectoryInfo directorySelected = new DirectoryInfo(directoryPath);
        Compress(directorySelected);

        foreach (FileInfo fileToDecompress in directorySelected.GetFiles("*.gz"))
        {
            Decompress(fileToDecompress);
        }
    }

    public static void Compress(DirectoryInfo directorySelected)
    {
        foreach (FileInfo fileToCompress in directorySelected.GetFiles())
        {
            using (FileStream originalFileStream = fileToCompress.OpenRead())
            {
                if ((File.GetAttributes(fileToCompress.FullName) &
                   FileAttributes.Hidden) != FileAttributes.Hidden & fileToCompress.Extension != ".gz")
                {
                    using (FileStream compressedFileStream = File.Create(fileToCompress.FullName + ".gz"))
                    {
                        using (GZipStream compressionStream = new GZipStream(compressedFileStream,
                           CompressionMode.Compress))
                        {
                            originalFileStream.CopyTo(compressionStream);
                        }
                    }
                    FileInfo info = new FileInfo(directoryPath + Path.DirectorySeparatorChar + fileToCompress.Name + ".gz");
                    Console.WriteLine($"Compressed {fileToCompress.Name} from {fileToCompress.Length.ToString()} to {info.Length.ToString()} bytes.");
                }
            }
        }
    }

    public static void Decompress(FileInfo fileToDecompress)
    {
        using (FileStream originalFileStream = fileToDecompress.OpenRead())
        {
            string currentFileName = fileToDecompress.FullName;
            string newFileName = currentFileName.Remove(currentFileName.Length - fileToDecompress.Extension.Length);

            using (FileStream decompressedFileStream = File.Create(newFileName))
            {
                using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress))
                {
                    decompressionStream.CopyTo(decompressedFileStream);
                    Console.WriteLine($"Decompressed: {fileToDecompress.Name}");
                }
            }
        }
    }
}

请参阅

你可能感兴趣的:(c语言,java,前端)