.NET C# 将文件夹压缩至 zip

.NET C# 将文件夹压缩至 zip

文章目录

  • [.NET C# 将文件夹压缩至 zip](# 将文件夹压缩至 zip)
    • [1 使用 System.IO.Compression](#1 使用 System.IO.Compression)
      • [1.1 环境](#1.1 环境)
      • [1.2 压缩文件夹](#1.2 压缩文件夹)
        • [1.2.1 简单压缩](#1.2.1 简单压缩)
        • [1.2.2 复杂压缩](#1.2.2 复杂压缩)
      • [1.3 解压缩](#1.3 解压缩)
        • [1.3.1 简单解压缩](#1.3.1 简单解压缩)
        • [1.3.2 复杂解压缩](#1.3.2 复杂解压缩)
    • [2 使用 SharpZipLib](#2 使用 SharpZipLib)
      • [2.1 环境](#2.1 环境)
      • [2.2 压缩文件夹](#2.2 压缩文件夹)
      • [2.3 解压缩](#2.3 解压缩)
    • [3 压缩效果简单测试](#3 压缩效果简单测试)

1 使用 System.IO.Compression

1.1 环境

  • .NET 6

1.2 压缩文件夹

1.2.1 简单压缩
csharp 复制代码
using System.IO.Compression;

string sourceDirectory = @"C:\path\to\your\folder"; // 需要压缩的文件夹路径
string destinationZipFilePath = @"C:\path\to\your\output.zip"; // 生成的zip文件路径
// 压缩文件夹
ZipFile.CreateFromDirectory(sourceDirectory, destinationZipFilePath);

注意事项

  • 请确保路径正确,并且具有对该路径的读写权限。
  • 如果目标zip文件已存在,该方法将覆盖该文件。如果你想避免覆盖,可以在压缩前检查文件是否存在,并进行相应处理。
1.2.2 复杂压缩

如果你需要更复杂的压缩选项,比如排除某些文件或文件夹,可以使用ZipArchive类来进行更细粒度的控制。

csharp 复制代码
using System.IO.Compression;

string sourceDirectory = @"C:\path\to\your\folder";
string destinationZipFilePath = @"C:\path\to\your\output.zip";

using (FileStream zipToOpen = new FileStream(destinationZipFilePath, FileMode.Create))
{
    using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Create))
    {
        DirectoryInfo directorySelected = new DirectoryInfo(sourceDirectory);

        foreach (FileInfo fileToCompress in directorySelected.GetFiles())
        {
            // 过滤特定文件(例如,排除所有.txt文件)
            if (fileToCompress.Extension == ".txt")
                continue;

            archive.CreateEntryFromFile(fileToCompress.FullName, fileToCompress.Name);
        }
    }
}

1.3 解压缩

1.3.1 简单解压缩
csharp 复制代码
using System.IO.Compression;

string sourceZipFilePath = @"C:\path\to\your\archive.zip"; // 需要解压缩的zip文件路径
string destinationDirectory = @"C:\path\to\your\output\folder"; // 解压缩到的目标文件夹路径
// 解压缩zip文件
ZipFile.ExtractToDirectory(sourceZipFilePath, destinationDirectory);

注意事项

  • 请确保路径正确,并且具有对该路径的读写权限。
  • 如果目标文件夹已存在且包含与zip文件中相同名称的文件,该方法将抛出异常。如果你想避免此问题,可以在解压缩前检查文件夹是否存在,并进行相应处理。
1.3.2 复杂解压缩
csharp 复制代码
using System.IO.Compression;

string sourceZipFilePath = @"C:\path\to\your\archive.zip";
string destinationDirectory = @"C:\path\to\your\output\folder";

using (ZipArchive archive = ZipFile.OpenRead(sourceZipFilePath))
{
    foreach (ZipArchiveEntry entry in archive.Entries)
    {
        // 解压缩所有文件到目标文件夹
        string destinationPath = Path.Combine(destinationDirectory, entry.FullName);

        // 如果条目是目录,则创建目录
        if (entry.Name == "")
        {
            Directory.CreateDirectory(destinationPath);
        }
        else
        {
            // 创建包含该条目的目录
            Directory.CreateDirectory(Path.GetDirectoryName(destinationPath));

            // 解压缩文件
            entry.ExtractToFile(destinationPath, overwrite: true);
        }
    }
}

2 使用 SharpZipLib

2.1 环境

  • .NET 6
  • SharpZipLib 1.4.2

2.2 压缩文件夹

csharp 复制代码
using System;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;

class Program
{
    static void Main()
    {
        string sourceDirectory = @"C:\path\to\your\folder"; // 需要压缩的文件夹路径
        string destinationZipFilePath = @"C:\path\to\your\output.zip"; // 生成的zip文件路径

        // 压缩文件夹
        CompressFolder(sourceDirectory, destinationZipFilePath);

        Console.WriteLine("文件夹已成功压缩到 " + destinationZipFilePath);
    }

    static void CompressFolder(string sourceDir, string zipFilePath)
    {
        // 创建目标zip文件
        using (FileStream fsOut = File.Create(zipFilePath))
        using (ZipOutputStream zipStream = new ZipOutputStream(fsOut))
        {
            zipStream.SetLevel(3); // 设置压缩级别(0-9)

            // 遍历源文件夹中的所有文件和目录
            int folderOffset = sourceDir.Length + (sourceDir.EndsWith("\\") ? 0 : 1);

            CompressDirectory(sourceDir, zipStream, folderOffset);
        }
    }

    static void CompressDirectory(string path, ZipOutputStream zipStream, int folderOffset)
    {
        string[] files = Directory.GetFiles(path);

        foreach (string filename in files)
        {
            FileInfo fi = new FileInfo(filename);

            string entryName = filename.Substring(folderOffset); // 创建条目名
            entryName = ZipEntry.CleanName(entryName); // 清理名称

            ZipEntry newEntry = new ZipEntry(entryName);
            newEntry.DateTime = fi.LastWriteTime; // 设置条目的日期时间
            newEntry.Size = fi.Length; // 设置条目的大小

            zipStream.PutNextEntry(newEntry);

            // 写入文件内容
            byte[] buffer = new byte[4096];
            using (FileStream streamReader = File.OpenRead(filename))
            {
                StreamUtils.Copy(streamReader, zipStream, buffer);
            }
            zipStream.CloseEntry();
        }

        // 递归处理目录
        string[] folders = Directory.GetDirectories(path);
        foreach (string folder in folders)
        {
            CompressDirectory(folder, zipStream, folderOffset);
        }
    }
}

2.3 解压缩

csharp 复制代码
using System;
using System.IO;
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;

class Program
{
    static void Main()
    {
        string sourceZipFilePath = @"C:\path\to\your\archive.zip"; // 需要解压缩的zip文件路径
        string destinationDirectory = @"C:\path\to\your\output\folder"; // 解压缩到的目标文件夹路径

        // 解压缩zip文件
        ExtractZipFile(sourceZipFilePath, destinationDirectory);

        Console.WriteLine("文件已成功解压缩到 " + destinationDirectory);
    }

    static void ExtractZipFile(string archiveFilenameIn, string outFolder)
    {
        ZipFile zf = null;
        try
        {
            FileStream fs = File.OpenRead(archiveFilenameIn);
            zf = new ZipFile(fs);

            foreach (ZipEntry zipEntry in zf)
            {
                if (!zipEntry.IsFile)
                {
                    continue; // 忽略目录条目
                }

                string entryFileName = zipEntry.Name;
                string fullZipToPath = Path.Combine(outFolder, entryFileName);
                string directoryName = Path.GetDirectoryName(fullZipToPath);

                // 创建目录
                if (directoryName.Length > 0)
                {
                    Directory.CreateDirectory(directoryName);
                }

                byte[] buffer = new byte[4096]; // 4K是推荐的缓冲区大小

                // 解压缩文件
                using (Stream zipStream = zf.GetInputStream(zipEntry))
                using (FileStream streamWriter = File.Create(fullZipToPath))
                {
                    StreamUtils.Copy(zipStream, streamWriter, buffer);
                }
            }
        }
        finally
        {
            if (zf != null)
            {
                zf.IsStreamOwner = true; // 使ZipFile也关闭文件流
                zf.Close();
            }
        }
    }
}

3 压缩效果简单测试

组件 压缩等级 耗时(ms) 结果数据大小(KB)
System.IO.Compression 1 24233 360197
5 35895 354376
9 137136 351221
SharpZipLib NoCompression 856 1046400
Fastest 11571 373848
Optimal 18642 353490
SmallestSize 85536 351208
相关推荐
△曉風殘月〆3 小时前
WPF MVVM入门系列教程(二、依赖属性)
c#·wpf·mvvm
逐·風5 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
m0_656974748 小时前
C#中的集合类及其使用
开发语言·c#
九鼎科技-Leo8 小时前
了解 .NET 运行时与 .NET 框架:基础概念与相互关系
windows·c#·.net
九鼎科技-Leo10 小时前
什么是 ASP.NET Core?与 ASP.NET MVC 有什么区别?
windows·后端·c#·asp.net·mvc·.net
.net开发10 小时前
WPF怎么通过RestSharp向后端发请求
前端·c#·.net·wpf
小乖兽技术11 小时前
C#与C++交互开发系列(二十):跨进程通信之共享内存(Shared Memory)
c++·c#·交互·ipc
幼儿园园霸柒柒11 小时前
第七章: 7.3求一个3*3的整型矩阵对角线元素之和
c语言·c++·算法·矩阵·c#·1024程序员节
平凡シンプル13 小时前
C# EF 使用
c#
丁德双14 小时前
winform 加载 office excel 插入QRCode图片如何设定位置
c#·excel