在C#开发中,文件夹的压缩与解压是常见需求,比如需要批量打包项目日志、处理用户上传的压缩包文件等。如果不想引入第三方压缩库,.NET框架自带的System.IO.Compression命名空间已经提供了完整的实现能力,下面我们就一步步实现相关功能。

准备工作
首先需要引入必要的命名空间,这些命名空间包含了压缩解压所需的全部类和方法:
using System; using System.IO; using System.IO.Compression;
实现文件夹压缩功能
压缩文件夹的核心思路是创建ZipArchive对象,然后遍历源文件夹下的所有文件,将每个文件添加到压缩包中,同时保留原有的目录结构。
压缩方法实现
/// <summary>
/// 压缩文件夹为zip文件
/// </summary>
/// <param name="sourceDirPath">要压缩的源文件夹路径</param>
/// <param name="zipFilePath">生成的zip文件路径</param>
public static void CompressDirectory(string sourceDirPath, string zipFilePath)
{
// 如果目标zip文件已存在,先删除
if (File.Exists(zipFilePath))
{
File.Delete(zipFilePath);
}
// 创建zip文件并打开写入流
using (FileStream zipFileStream = new FileStream(zipFilePath, FileMode.Create))
using (ZipArchive archive = new ZipArchive(zipFileStream, ZipArchiveMode.Create))
{
// 获取源文件夹下所有文件,包含子目录
string[] files = Directory.GetFiles(sourceDirPath, "*", SearchOption.AllDirectories);
foreach (string filePath in files)
{
// 计算文件在压缩包中的相对路径,保留目录结构
string relativePath = filePath.Substring(sourceDirPath.Length + 1);
// 创建压缩包中的条目
ZipArchiveEntry entry = archive.CreateEntry(relativePath, CompressionLevel.Optimal);
// 写入文件内容
using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
using (Stream entryStream = entry.Open())
{
fileStream.CopyTo(entryStream);
}
}
}
Console.WriteLine($"文件夹压缩完成,生成文件:{zipFilePath}");
}方法说明
ZipArchiveMode.Create表示创建新的压缩包,如果已存在会报错,所以提前做了删除处理CompressionLevel.Optimal是最高压缩等级,也可以选择CompressionLevel.Fastest提升速度但压缩率稍低- 通过截取源文件夹路径长度得到相对路径,确保解压后目录结构和原文件夹一致
实现文件夹解压功能
解压功能的核心是读取zip文件中的条目,创建对应的目录结构,然后将条目内容写入到目标路径的文件中。
解压方法实现
/// <summary>
/// 解压zip文件到目标文件夹
/// </summary>
/// <param name="zipFilePath">要解压的zip文件路径</param>
/// <param name="targetDirPath">解压到的目标文件夹路径</param>
public static void DecompressDirectory(string zipFilePath, string targetDirPath)
{
// 如果目标文件夹不存在,创建文件夹
if (!Directory.Exists(targetDirPath))
{
Directory.CreateDirectory(targetDirPath);
}
// 打开zip文件读取
using (FileStream zipFileStream = new FileStream(zipFilePath, FileMode.Open, FileAccess.Read))
using (ZipArchive archive = new ZipArchive(zipFileStream, ZipArchiveMode.Read))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
// 构建目标文件的完整路径
string targetFilePath = Path.Combine(targetDirPath, entry.FullName);
// 如果是目录条目,创建目录
if (string.IsNullOrEmpty(entry.Name))
{
Directory.CreateDirectory(targetFilePath);
continue;
}
// 确保目标文件的目录存在
string targetFileDir = Path.GetDirectoryName(targetFilePath);
if (!Directory.Exists(targetFileDir))
{
Directory.CreateDirectory(targetFileDir);
}
// 写入文件内容
using (Stream entryStream = entry.Open())
using (FileStream fileStream = new FileStream(targetFilePath, FileMode.Create, FileAccess.Write))
{
entryStream.CopyTo(fileStream);
}
}
}
Console.WriteLine($"zip文件解压完成,解压到路径:{targetDirPath}");
}方法说明
ZipArchiveMode.Read表示以读取模式打开压缩包- 条目分为文件条目和目录条目,目录条目的
Name属性为空,需要单独处理创建目录 - 解压前先确保目标文件的父目录存在,避免写入文件时报错
功能测试
我们可以编写一个简单的测试方法验证上述功能是否正常:
class Program
{
static void Main(string[] args)
{
string testSourceDir = @"D:\TestSourceDir"; // 测试源文件夹,需要提前创建并放入一些文件
string testZipPath = @"D:\TestCompressed.zip"; // 生成的压缩包路径
string testTargetDir = @"D:\TestDecompressedDir"; // 解压目标路径
try
{
// 测试压缩
CompressDirectory(testSourceDir, testZipPath);
// 测试解压
DecompressDirectory(testZipPath, testTargetDir);
Console.WriteLine("测试完成,功能正常");
}
catch (Exception ex)
{
Console.WriteLine($"操作失败,错误信息:{ex.Message}");
}
}
}注意事项
- 操作文件时需要确保程序对源文件夹、目标路径有足够的读写权限,否则会抛出UnauthorizedAccessException异常
- 如果压缩的文件夹中包含超大文件,建议分块处理或者添加进度提示,避免界面卡死
- 处理用户输入的路径时,需要做好合法性校验,避免路径注入等安全问题
C#文件夹压缩文件夹解压ZipArchiveSystem.IO.Compression修改时间:2026-05-29 03:57:24