using ICSharpCode.SharpZipLib.Zip;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ExternalDataSync.MessageHanlder
{
///
/// 适用于ZIP压缩
///
public class ZipHelper
{
#region 压缩
///
/// 压缩文件夹
///
/// 要压缩的文件夹路径
/// 压缩前的Stream,方法执行后变为压缩完成后的文件
/// 密码
/// 是否成功
public static bool ZipDirectoryToStream(string folderToZip, Stream Stream, string password = null)
{
return ZipDirectoryToZipStream(folderToZip, Stream, password) != null;
}
///
/// 压缩文件夹
///
/// 要压缩的文件夹路径
/// 压缩前的Stream,方法执行后变为压缩完成后的文件
/// 密码
/// 是否压缩成功返回ZipOutputStream,否则返回null
public static ZipOutputStream ZipDirectoryToZipStream(string folderToZip, Stream Stream, string password = null)
{
if (!Directory.Exists(folderToZip))
{
return null;
}
ZipOutputStream zipStream = new ZipOutputStream(Stream);
zipStream.SetLevel(6);
if (!string.IsNullOrEmpty(password))
{
zipStream.Password = password;
}
if (ZipDirectory(folderToZip, zipStream, ""))
{
zipStream.Finish();
return zipStream;
}
GC.Collect(1);
return null;
}
///
/// 递归压缩文件夹的内部方法
///
/// 要压缩的文件夹路径
/// 压缩输出流
/// 此文件夹的上级文件夹
/// 是否成功
private static bool ZipDirectory(string folderToZip, ZipOutputStream zipStream, string parentFolderName)
{
var crc = new ICSharpCode.SharpZipLib.Checksum.Crc32();
//这段是创建空文件夹,注释掉可以去掉空文件夹(因为在写入文件的时候也会创建文件夹)
//if (!string.IsNullOrEmpty(parentFolderName))
//{
// ent = new ZipEntry(parentFolderName + "/");
// zipStream.PutNextEntry(ent);
// zipStream.Flush();
//}
var files = Directory.GetFiles(folderToZip);
foreach (string file in files)
{
byte[] buffer = File.ReadAllBytes(file);
var ent = new ZipEntry(parentFolderName + "/" + Path.GetFileName(file));
//ent.DateTime = File.GetLastWriteTime(file);//设置文件最后修改时间
ent.DateTime = DateTime.Now;
ent.Size = buffer.Length;
crc.Reset();
crc.Update(buffer);
ent.Crc = crc.Value;
zipStream.PutNextEntry(ent);
zipStream.Write(buffer, 0, buffer.Length);
}
var folders = Directory.GetDirectories(folderToZip);
foreach (var folder in folders)
{
var _parentFolderName = parentFolderName + "\\" + folder.Substring(folder.LastIndexOf('\\') + 1);
if (!ZipDirectory(folder, zipStream, _parentFolderName))
{
return false;
}
}
return true;
}
///
/// 压缩文件夹
///
/// 要压缩的文件夹路径
/// 压缩文件完整路径
/// 密码
/// 是否成功
public static bool ZipDirectory(string folderToZip, string zipedFile, string password = null)
{
var zipStream = ZipDirectoryToZipStream(folderToZip, new FileStream(zipedFile, FileMode.Create, FileAccess.Write), password);
if (zipStream == null)
{
return false;
}
zipStream.Close();
return true;
}
///
/// 压缩文件
///
/// 要压缩的文件全名
/// 压缩后的文件名
/// 密码
/// 是否成功
public static bool ZipFile(string fileToZip, string zipedFile, string password = null)
{
if (!File.Exists(fileToZip))
{
return false;
}
var fs = File.OpenRead(fileToZip);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Close();
fs = File.Create(zipedFile);
var ent = new ZipEntry(Path.GetFileName(fileToZip));
using (var zipStream = new ZipOutputStream(fs))
{
if (!string.IsNullOrEmpty(password))
{
zipStream.Password = password;
}
zipStream.PutNextEntry(ent);
zipStream.SetLevel(6);
zipStream.Write(buffer, 0, buffer.Length);
}
if (fs != null)
{
fs.Close();
fs.Dispose();
}
GC.Collect(1);
return true;
}
///
/// 压缩文件或文件夹
///
/// 要压缩的路径
/// 压缩后的文件名
/// 密码
/// 是否成功
public static bool Zip(string fileToZip, string zipedFile, string password = null)
{
if (Directory.Exists(fileToZip))
{
return ZipDirectory(fileToZip, zipedFile, password);
}
else if (File.Exists(fileToZip))
{
return ZipFile(fileToZip, zipedFile, password);
}
return false;
}
#endregion
#region 解压
///
/// 解压功能(解压压缩文件到指定目录)
///
/// 待解压的文件
/// 指定解压目标目录
/// 密码
/// 是否成功
public static bool UnZip(string fileToUnZip, string zipedFolder, string password = null)
{
if (!System.IO.File.Exists(fileToUnZip))
{
return false;
}
if (!Directory.Exists(zipedFolder))
{
Directory.CreateDirectory(zipedFolder);
}
if (!zipedFolder.EndsWith("\\"))
{
zipedFolder += "\\";
}
ZipEntry ent = null;
using (var zipStream = new ZipInputStream(System.IO.File.OpenRead(fileToUnZip)))
{
if (!string.IsNullOrEmpty(password))
{
zipStream.Password = password;
}
while ((ent = zipStream.GetNextEntry()) != null)
{
if (ent.IsDirectory)
{
continue;
}
if (string.IsNullOrEmpty(ent.Name))
{
continue;
}
string fileName = zipedFolder + ent.Name.Replace('/', '\\');
var index = ent.Name.LastIndexOf('/');
if (index != -1)
{
string path = zipedFolder + ent.Name.Substring(0, index).Replace('/', '\\');
System.IO.Directory.CreateDirectory(path);
}
var bytes = new byte[ent.Size];
zipStream.Read(bytes, 0, bytes.Length);
System.IO.File.WriteAllBytes(fileName, bytes);
}
}
GC.Collect(1);
return true;
}
#endregion
}
}