246 lines
8.7 KiB
C#
246 lines
8.7 KiB
C#
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
|
||
{
|
||
/// <summary>
|
||
/// 适用于ZIP压缩
|
||
/// </summary>
|
||
public class ZipHelper
|
||
{
|
||
#region 压缩
|
||
/// <summary>
|
||
/// 压缩文件夹
|
||
/// </summary>
|
||
/// <param name="folderToZip">要压缩的文件夹路径</param>
|
||
/// <param name="Stream">压缩前的Stream,方法执行后变为压缩完成后的文件</param>
|
||
/// <param name="password">密码</param>
|
||
/// <returns>是否成功</returns>
|
||
public static bool ZipDirectoryToStream(string folderToZip, Stream Stream, string password = null)
|
||
{
|
||
return ZipDirectoryToZipStream(folderToZip, Stream, password) != null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 压缩文件夹
|
||
/// </summary>
|
||
/// <param name="folderToZip">要压缩的文件夹路径</param>
|
||
/// <param name="Stream">压缩前的Stream,方法执行后变为压缩完成后的文件</param>
|
||
/// <param name="password">密码</param>
|
||
/// <returns>是否压缩成功返回ZipOutputStream,否则返回null</returns>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 递归压缩文件夹的内部方法
|
||
/// </summary>
|
||
/// <param name="folderToZip">要压缩的文件夹路径</param>
|
||
/// <param name="zipStream">压缩输出流</param>
|
||
/// <param name="parentFolderName">此文件夹的上级文件夹</param>
|
||
/// <returns>是否成功</returns>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 压缩文件夹
|
||
/// </summary>
|
||
/// <param name="folderToZip">要压缩的文件夹路径</param>
|
||
/// <param name="zipedFile">压缩文件完整路径</param>
|
||
/// <param name="password">密码</param>
|
||
/// <returns>是否成功</returns>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 压缩文件
|
||
/// </summary>
|
||
/// <param name="fileToZip">要压缩的文件全名</param>
|
||
/// <param name="zipedFile">压缩后的文件名</param>
|
||
/// <param name="password">密码</param>
|
||
/// <returns>是否成功</returns>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 压缩文件或文件夹
|
||
/// </summary>
|
||
/// <param name="fileToZip">要压缩的路径</param>
|
||
/// <param name="zipedFile">压缩后的文件名</param>
|
||
/// <param name="password">密码</param>
|
||
/// <returns>是否成功</returns>
|
||
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 解压
|
||
/// <summary>
|
||
/// 解压功能(解压压缩文件到指定目录)
|
||
/// </summary>
|
||
/// <param name="fileToUnZip">待解压的文件</param>
|
||
/// <param name="zipedFolder">指定解压目标目录</param>
|
||
/// <param name="password">密码</param>
|
||
/// <returns>是否成功</returns>
|
||
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
|
||
}
|
||
|
||
}
|