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

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

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

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);
Imports System.IO.Compression
Module Module1
    Sub Main()
        Dim startPath As String = ".\start"
        Dim zipPath As String = ".\result.zip"
        Dim extractPath As String = ".\extract"
        ZipFile.CreateFromDirectory(startPath, zipPath)
        ZipFile.ExtractToDirectory(zipPath, extractPath)
    End Sub
End Module

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

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

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

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

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);
Imports System.IO
Imports System.IO.Compression
Module Module1
    Sub Main()
        Dim zipPath As String = ".\result.zip"
        Console.WriteLine("Provide path where to extract the zip file:")
        Dim extractPath As String = 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 Not extractPath.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal) Then
            extractPath += Path.DirectorySeparatorChar
        End If
        Using archive As ZipArchive = ZipFile.OpenRead(zipPath)
            For Each entry As ZipArchiveEntry In archive.Entries
                If entry.FullName.EndsWith(".txt", StringComparison.OrdinalIgnoreCase) Then
                    ' Gets the full path to ensure that relative segments are removed.
                    Dim destinationPath As String = 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) Then
                        entry.ExtractToFile(destinationPath)
                    End If
                End If
        End Using
    End Sub
End Module

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

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

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("========================");
Imports System.IO
Imports System.IO.Compression
Module Module1
    Sub Main()
        Using zipToOpen As FileStream = New FileStream("c:\users\exampleuser\release.zip", FileMode.Open)
            Using archive As ZipArchive = New ZipArchive(zipToOpen, ZipArchiveMode.Update)
                Dim readmeEntry As ZipArchiveEntry = archive.CreateEntry("Readme.txt")
                Using writer As StreamWriter = New StreamWriter(readmeEntry.Open())
                    writer.WriteLine("Information about this package.")
                    writer.WriteLine("========================")
                End Using
            End Using
        End Using
    End Sub
End Module

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

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

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}");
Imports System.IO
Imports System.IO.Compression
Module Module1
    Private directoryPath As String = ".\temp"
    Public Sub Main()
        Dim directorySelected As New DirectoryInfo(directoryPath)
        Compress(directorySelected)
        For Each fileToDecompress As FileInfo In directorySelected.GetFiles("*.gz")
            Decompress(fileToDecompress)
    End Sub
    Public Sub Compress(directorySelected As DirectoryInfo)
        For Each fileToCompress As FileInfo In directorySelected.GetFiles()
            Using originalFileStream As FileStream = fileToCompress.OpenRead()
                If (File.GetAttributes(fileToCompress.FullName) And FileAttributes.Hidden) <> FileAttributes.Hidden And fileToCompress.Extension <> ".gz" Then
                    Using compressedFileStream As FileStream = File.Create(fileToCompress.FullName & ".gz")
                        Using compressionStream As New GZipStream(compressedFileStream, CompressionMode.Compress)
                            originalFileStream.CopyTo(compressionStream)
                        End Using
                    End Using
                    Dim info As New FileInfo(directoryPath & Path.DirectorySeparatorChar & fileToCompress.Name & ".gz")
                    Console.WriteLine($"Compressed {fileToCompress.Name} from {fileToCompress.Length.ToString()} to {info.Length.ToString()} bytes.")
                End If
            End Using
    End Sub
    Private Sub Decompress(ByVal fileToDecompress As FileInfo)
        Using originalFileStream As FileStream = fileToDecompress.OpenRead()
            Dim currentFileName As String = fileToDecompress.FullName
            Dim newFileName = currentFileName.Remove(currentFileName.Length - fileToDecompress.Extension.Length)
            Using decompressedFileStream As FileStream = File.Create(newFileName)
                Using decompressionStream As GZipStream = New GZipStream(originalFileStream, CompressionMode.Decompress)
                    decompressionStream.CopyTo(decompressedFileStream)
                    Console.WriteLine($"Decompressed: {fileToDecompress.Name}")
                End Using
            End Using
        End Using
    End Sub
End Module
  • ZipArchive
  • ZipFile
  • ZipArchiveEntry
  • DeflateStream
  • GZipStream
  • 文件和流 I/O
  • 即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:https://aka.ms/ContentUserFeedback

    提交和查看相关反馈