winform中使用带有密码压缩的方法之一
使用dotnetzip的方式
1.添加引用,因开发的是win7常用的,引用了1.12.0.0版本;
2.编写一个静态类;
using Ionic.Zip;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace rarTest
{
public class DotNetZip
{ /// <summary>
/// 压缩文件/文件夹,支持相对路径
/// </summary>
/// <param name="filePath">需要压缩的文件/文件夹路径</param>
/// <param name="zipPath">压缩文件路径(zip后缀)</param>
/// <param name="password">密码</param>
/// <param name="filterExtenList">需要过滤的文件后缀名</param>
public static void CompressionFile(string filePath, string zipPath, string password = "", List<string> filterExtenList = null)
{
try
{
using (ZipFile zip = new ZipFile(Encoding.UTF8))
{
if (!string.IsNullOrEmpty(password))//这是net4.0的版本IsNullOrWhiteSpace
{
zip.Password = password;
}
if (Directory.Exists(filePath))
{
if (filterExtenList == null)
zip.AddDirectory(filePath);
else
AddDirectory(zip, filePath, filePath, filterExtenList);
}
else if (File.Exists(filePath))
{
zip.AddFile(filePath, "");
}
zip.Save(zipPath);
}
}
catch (Exception ex)
{
LogHelper.error("压缩数据发生错误:" + ex.Message);
throw ex;
}
}
/// <summary>
/// 添加文件夹
/// </summary>
/// <param name="zip">ZipFile对象</param>
/// <param name="dirPath">需要压缩的文件夹路径</param>
/// <param name="rootPath">根目录路径</param>
/// <param name="filterExtenList">需要过滤的文件后缀名</param>
public static void AddDirectory(ZipFile zip, string dirPath, string rootPath, List<string> filterExtenList)
{
var files = Directory.GetFiles(dirPath);
for (int i = 0; i < files.Length; i++)
{
//如果Contains不支持第二个参数,就用.ToLower()//Contains(d, StringComparison.OrdinalIgnoreCase)
if (filterExtenList == null || (filterExtenList != null && !filterExtenList.Any(d => Path.GetExtension(files[i]).Contains(d.ToLower()))))
{
//获取相对路径作为zip文件中目录路径
// zip.AddFile(files[i], Path.GetRelativePath(rootPath, dirPath));
//如果没有Path.GetRelativePath方法,可以用下面代码替换
string relativePath = Path.GetFullPath(dirPath).Replace(Path.GetFullPath(rootPath), "");
zip.AddFile(files[i], relativePath);
}
}
var dirs = Directory.GetDirectories(dirPath);
for (int i = 0; i < dirs.Length; i++)
{
AddDirectory(zip, dirs[i], rootPath, filterExtenList);
}
}
public static void CompressionFileList(string[] filelist, string zipPath, string password = "", List<string> filterExtenList = null)
{
try
{
using (ZipFile zip = new ZipFile(Encoding.UTF8))
{
if (!string.IsNullOrEmpty(password))//这是net4.0的版本IsNullOrWhiteSpace
{
zip.Password = password;
}
for (int i = 0; i < filelist.Length; i++)
{
if (File.Exists(filelist[i]))
{
zip.AddFile(filelist[i], "");
}
}
zip.Save(zipPath);
// LogHelper.error("压缩数据发生了:");
}
}
catch (Exception ex)
{
LogHelper.error("压缩数据发生错误:" + ex.Message);
throw ex;
}
}
/// <summary>
/// 解压文件
/// </summary>
/// <param name="zipPath">需要解压的文件</param>
/// <param name="dirPath">解压到位置</param>
/// <param name="password">解压密码</param>
public static void DeCompressionFile(string zipPath, string dirPath, string password = "")
{
if (!File.Exists(zipPath))
{
throw new ArgumentNullException("zipPath压缩文件不存在");
}
Directory.CreateDirectory(dirPath);
try
{
using (ZipFile zip = new ZipFile(zipPath))
{
if (!string.IsNullOrEmpty(password))//这是net4.0的版本IsNullOrWhiteSpace
{
zip.Password = password;
}
zip.ExtractAll(dirPath, ExtractExistingFileAction.OverwriteSilently);
}
}
catch (Exception ex)
{
LogHelper.error("解压数据发生错误:" + ex.Message);
throw ex;//如何写到文件中
}
}
}
}
使用的时候可以在对应的窗口中使用:
// 使用方法
string sourceFolder = @"文件夹";
string destinationZip = @"文件夹.aa";
DotNetZip.CompressionFile(sourceFolder, destinationZip,"123");
如果涉及到进度条
建议把上面的DotNetZip,改成非静态的ziphelper类,添加对应的参数例如下面的
// 示例:压缩文件并更新进度,一般下面的方法不能用静态的static
public int progress = 0;
public event Action<int> callBack;
public void CreateZip(string[] filelist, string zipPath, string password = "", List<string> filterExtenList = null)
{
try
{
progress = 0;
using (ZipFile zip = new ZipFile(Encoding.UTF8))
{
// zip.UseZip64WhenSaving = Zip64Option.Always; // 启用ZIP64格式支持
// zip.AlternateEncoding = System.Text.Encoding.UTF8; // 使用 UTF-8 编码
zip.AlternateEncodingUsage = ZipOption.Always; // 始终使用指定编码
// 订阅SaveProgress事件
zip.SaveProgress += (sender, e) =>
{
if (e.EventType == ZipProgressEventType.Saving_BeforeWriteEntry)
{
progress = (int)((e.EntriesSaved / (float)e.EntriesTotal) * 100);
this.callBack?.Invoke(progress);
}
else if (e.EventType == ZipProgressEventType.Saving_Completed)
{
this.callBack?.Invoke(100); // 确保在完成时报告100%进度
}
};
if (!string.IsNullOrEmpty(password))//这是net4.0的版本IsNullOrWhiteSpace
{
zip.Password = password;
}
foreach (var item in filelist)
{
if (File.Exists(item))
{
zip.AddFile(item, "");
}
else if (Directory.Exists(item))
{
zip.AddDirectory(item, Path.GetFileName(item));
}
}
zip.Save(zipPath);
}
}
catch (Exception ex)
{
LogHelper.error("压缩数据发生错误:" + ex.Message);
throw ex;
}
}
// 示例:解压缩文件并更新进度
public void ExtractZip(string zipFilePath, string outputFolder, string taskId, string password = "")
{
progress = 0;
if (!Directory.Exists(outputFolder))
{
Directory.CreateDirectory(outputFolder);
}
using (ZipFile zip = ZipFile.Read(zipFilePath))
{
zip.AlternateEncoding = System.Text.Encoding.UTF8; // 使用 UTF-8 编码
zip.AlternateEncodingUsage = ZipOption.Always; // 始终使用指定编码
if (!string.IsNullOrEmpty(password))//这是net4.0的版本IsNullOrWhiteSpace
{
zip.Password = password;
}
int total = zip.Count;
int current = 0;
foreach (ZipEntry e in zip)
{
try
{
e.Extract(outputFolder, ExtractExistingFileAction.OverwriteSilently);
current++;
progress = (int)((current / (float)total) * 100);
this.callBack?.Invoke(progress);
}
catch (IOException ex)
{
Console.WriteLine($"无法解压文件:{e.FileName},错误:{ex.Message}");
// 考虑是否需要在此处更新进度或处理异常
LogHelper.error($"无法解压文件:{e.FileName},错误:{ex.Message}");
continue;
}
}
}
}
对应的使用:同上面的方式,
ziphelper.callBack += new Action<int>((i) =>
{
this.progressBar1.Value = i;
});
ziphelper.CreateZip("文件夹", "prge66666123.zip", "123");