.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 |