用c#写一个创建有密码的zip压缩文件,带进度百分比,可以取消压缩
时间: 2024-09-24 20:29:08 浏览: 36
在 C# 中,你可以使用 `System.IO.Compression.ZipFile` 类来创建 ZIP 压缩文件,并结合 `Task` 和 `Progress<T>` 来跟踪压缩过程中的进度百分比。以下是一个简单的示例,展示了如何编写这样的功能,同时允许用户取消压缩:
```csharp
using System;
using System.IO;
using System.IO.Compression;
using System.Threading.Tasks;
public class ZipProgress : IProgress<int>
{
private int _progress;
public event EventHandler ProgressChanged;
public void Report(int value)
{
_progress = value;
OnProgressChanged();
}
protected virtual void OnProgressChanged()
{
if (ProgressChanged != null)
ProgressChanged(this, EventArgs.Empty);
}
}
class Program
{
static async Task Main(string[] args)
{
string sourceFolder = "YourSourceDirectory";
string zipFilePath = "YourDestinationZip.zip";
ZipProgress zipProgress = new ZipProgress();
CancellationTokenSource cts = new CancellationTokenSource();
// 压缩操作
await CompressFolder(sourceFolder, zipFilePath, zipProgress, cts.Token);
Console.WriteLine("Compression completed.");
// 示例:监听是否取消压缩
if (cts.IsCancellationRequested)
Console.WriteLine("Compression was canceled.");
}
private static async Task CompressFolder(
string sourceFolder,
string zipPath,
IProgress<int> progress,
CancellationToken cancellationToken)
{
try
{
using (var archive = new ZipArchive(zipPath, ZipArchiveMode.Create, true))
{
var progressBarMax = GetFilesCount(sourceFolder);
foreach (string folderOrFile in Directory.GetFiles(sourceFolder) ?? Array.Empty<string>())
{
var fileName = Path.GetFileName(folderOrFile);
if (!cancellationToken.IsCancellationRequested)
{
var entry = archive.CreateEntry(fileName, CompressionLevel.Optimal);
CopyAndTrackFile(entry.Open(), folderOrFile, progress, cancellationToken);
}
}
}
}
catch (OperationCanceledException)
{
Console.WriteLine("Compression canceled by user.");
}
}
private static int GetFilesCount(string path)
{
try
{
return Directory.GetFiles(path)?.Length ?? 0;
}
catch (IOException)
{
return 0;
}
}
private static void CopyAndTrackFile(Stream destination, string sourceFile, IProgress<int> progress, CancellationToken cancellationToken)
{
long totalBytesToWrite = new FileInfo(sourceFile).Length;
byte[] buffer = new byte[4096];
using (FileStream sourceFileStream = File.OpenRead(sourceFile))
{
while ((totalBytesToWrite > 0) && !cancellationToken.IsCancellationRequested)
{
int bytesRead = sourceFileStream.Read(buffer, 0, buffer.Length);
if (bytesRead > 0)
{
destination.Write(buffer, 0, bytesRead);
progress.Report((int)(bytesRead * 100 / totalBytesToWrite));
totalBytesToWrite -= bytesRead;
}
else
{
break;
}
}
}
}
}
```
在这个示例中,`CompressFolder` 方法接收源目录、目标ZIP文件路径、进度处理器以及一个 `CancellationTokenSource`,用于监听是否需要取消操作。如果用户按下取消按钮,`CancellationToken` 将会发送信号,导致压缩操作中断。
阅读全文