压缩、解压缩zip文件 ZipArchive
Demo
ZipArchiveHelper.CreateZipFileFromDirectory(srcDir, zipFile);
......
ZipArchiveHelper.UnZip(zipFile, tempDir);
ZipArchiveHelper.CopyDirectory(tempDir, dstDir);
ZipArchiveHelper.DeleteFolder(tempDir);
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text.RegularExpressions;
public static class ZipArchiveHelper
{
/// <summary>
/// 创建 zip 存档,该存档包括指定目录的文件和目录,使用指定压缩级别,以及可以选择包含基目录。
/// </summary>
/// <param name="srcDirectory">要存档的目录或文件</param>
/// <param name="dstFileName">要生成的文件(当前目录或绝对路径)</param>
/// <param name="compressionLevel">压缩级别</param>
/// <param name="bIncludeBaseDiretory">压缩包中是否包含父目录</param>
/// <returns></returns>
public static bool CreateZipFileFromDirectory(string srcDirectory, string dstFileName, CompressionLevel compressionLevel = CompressionLevel.Fastest, bool bIncludeBaseDiretory = true)
{
try
{
if (Directory.Exists(srcDirectory))
{
if (!File.Exists(dstFileName))
{
ZipFile.CreateFromDirectory(srcDirectory, dstFileName, compressionLevel, bIncludeBaseDiretory);
}
else
{
var infoDic = GetAllDirList(srcDirectory, bIncludeBaseDiretory);
using (var archive = ZipFile.Open(dstFileName, ZipArchiveMode.Update))
{
foreach (var key in infoDic.Keys)
{
if (key != dstFileName)
{
var fileName = Path.GetFileName(key);
var entryList = new List<ZipArchiveEntry>();
foreach (var entry in archive.Entries)
{
if (fileName != null && (entry.FullName.StartsWith(fileName) || fileName.StartsWith(entry.FullName)))
{
entryList.Add(entry);
}
}
entryList.ForEach(x => x.Delete());
archive.CreateEntryFromFile(key, infoDic[key], compressionLevel);
}
}
}
}
}
else if (File.Exists(srcDirectory))
{
if (!File.Exists(dstFileName))
{
ZipFile.CreateFromDirectory(srcDirectory, dstFileName, compressionLevel, false);
}
else
{
using (var archive = ZipFile.Open(dstFileName, ZipArchiveMode.Update))
{
if (srcDirectory != dstFileName)
{
var fileName = Path.GetFileName(srcDirectory);
var entryList = new List<ZipArchiveEntry>();
foreach (var entry in archive.Entries)
{
if (fileName != null && (entry.FullName.StartsWith(fileName) || fileName.StartsWith(entry.FullName)))
{
entryList.Add(entry);
}
}
entryList.ForEach(x => x.Delete());
archive.CreateEntryFromFile(srcDirectory, fileName, compressionLevel);
}
}
}
}
else
{
return false;
}
return true;
}
catch (Exception ex)
{
string err = ex.Message;
return false;
}
}
/// <summary>
/// 获取目录下所有[文件名,要压缩的相对文件名]字典
/// </summary>
/// <param name="srcDirectory"></param>
/// <param name="bIncludeBaseDiretory"></param>
/// <param name="prefix"></param>
/// <returns></returns>
private static Dictionary<string, string> GetAllDirList(string srcDirectory, bool bIncludeBaseDiretory = false, string prefix = "")
{
var rslt = new Dictionary<string, string>();
var info = new DirectoryInfo(srcDirectory);
if (bIncludeBaseDiretory)
{
prefix += info.Name + "\\";
}
foreach (var dir in info.GetDirectories())
{
rslt = rslt.Concat(GetAllDirList(dir.FullName, true, prefix)).ToDictionary(k => k.Key, k => k.Value);
foreach (var file in info.GetFiles())
{
if (!rslt.ContainsKey(file.FullName))
{
rslt.Add(file.FullName, prefix + info.Name);
}
}
}
return rslt;
}
public static bool UnZip(string zipFile, string dstDir)
{
bool rslt = false;
try
{
dstDir = dstDir.EndsWith(@"\") ? dstDir : dstDir + @"\";
var info = new DirectoryInfo(dstDir);
if (!info.Exists)
{
info.Create();
}
var fi = new FileInfo(zipFile);
if (!fi.Exists)
{
return false;
}
using (var fs = new FileStream(zipFile, FileMode.Open, FileAccess.ReadWrite, FileShare.Read))
{
using (var archive = new ZipArchive(fs, ZipArchiveMode.Read))
{
foreach (var entry in archive.Entries)
{
if (!entry.FullName.EndsWith("/"))
{
var entryFilePath = Regex.Replace(entry.FullName.Replace("/", @"\"), @"^\\*", "");
var filePath = info + entryFilePath;
var content = new byte[entry.Length];
entry.Open().Read(content, 0, content.Length);
if (File.Exists(filePath) && content.Length == new FileInfo(filePath).Length)
{
// 跳过相同的文件,否则覆盖更新
continue;
}
var sameInfo = new DirectoryInfo(filePath);
if (sameInfo.Exists)
{
sameInfo.Delete(true);
DeleteDirectoryWithCmd(filePath);
}
var sameFi = new FileInfo(filePath);
if (sameFi.Exists)
{
sameFi.Delete();
DeleteFileWithCmd(filePath);
}
var parentInfo = Directory.GetParent(filePath);
if (!parentInfo.Exists)
{
parentInfo.Create();
}
File.WriteAllBytes(filePath, content);
}
}
}
}
rslt = true;
}
catch (Exception ex)
{
string err = ex.Message;
return false;
}
return rslt;
}
/// <summary>
/// 调用bat删除目录,以防止系统底层的异步删除机制
/// </summary>
/// <param name="dir"></param>
private static bool DeleteFileWithCmd(string dir)
{
var p = new Process();
var info = new ProcessStartInfo("CMD.EXE", "/C rd /S /Q \"" + dir + "\"")
{
UseShellExecute = false,
RedirectStandardOutput = true,
};
p.StartInfo = info;
p.Start();
p.WaitForExit();
var output = p.StandardOutput.ReadToEnd();
if (string.IsNullOrWhiteSpace(output))
{
return true;
}
return false;
}
/// <summary>
/// 调用bat删除文件,以防止系统底层的异步删除机制
/// </summary>
/// <param name="filePath"></param>
private static bool DeleteDirectoryWithCmd(string filePath)
{
var p = new Process();
var info = new ProcessStartInfo("CMD.EXE", "/C del /F /S /Q \"" + filePath + "\"")
{
UseShellExecute = false,
RedirectStandardOutput = true,
};
p.StartInfo = info;
p.Start();
p.WaitForExit();
var output = p.StandardOutput.ReadToEnd();
if (output.Contains(filePath))
{
return true;
}
return false;
}
/// <summary>
/// 创建 zip 存档,该存档包含指定目录的文件和目录。
/// </summary>
/// <param name="srcDir">要存档的目录</param>
/// <param name="dstFileName">要生成的存档</param>
/// <param name="compressionLevel">压缩级别</param>
/// <returns></returns>
public static bool CreateZipFileFromDictionary(Dictionary<string, string> srcDir, string dstFileName, CompressionLevel compressionLevel = CompressionLevel.Fastest)
{
try
{
using (FileStream fs = new FileStream(dstFileName, FileMode.OpenOrCreate))
{
using (ZipArchive archive = new ZipArchive(fs, ZipArchiveMode.Update))
{
foreach (var key in srcDir.Keys)
{
if (key != dstFileName)
{
var fileName = Path.GetFileName(key);
var entryList = new List<ZipArchiveEntry>();
foreach (var entry in archive.Entries)
{
if (fileName != null && (entry.FullName.StartsWith(fileName) || fileName.StartsWith(entry.FullName)))
{
entryList.Add(entry);
}
}
entryList.ForEach(x => x.Delete());
archive.CreateEntryFromFile(key, srcDir[key], compressionLevel);
}
}
}
}
return true;
}
catch (Exception ex)
{
string er = ex.Message;
return false;
}
}
/// <summary>
/// 递归拷贝文件夹目录及文件
/// </summary>
/// <param name="srcDir"></param>
/// <param name="dstDir"></param>
/// <param name="bOverwrite">默认覆盖拷贝</param>
/// <returns></returns>
public static bool CopyDirectory(string srcDir, string dstDir, bool bOverwrite = true)
{
bool rslt = false;
try
{
srcDir = srcDir.EndsWith(@"\") ? srcDir : srcDir + @"\";
dstDir = dstDir.EndsWith(@"\") ? dstDir : dstDir + @"\";
if (Directory.Exists(srcDir))
{
if (!Directory.Exists(dstDir))
{
Directory.CreateDirectory(dstDir);
}
foreach (var item in Directory.GetFiles(srcDir))
{
FileInfo fi = new FileInfo(item);
fi.CopyTo(dstDir + fi.Name, bOverwrite);
}
foreach (var dir in Directory.GetDirectories(srcDir))
{
DirectoryInfo di = new DirectoryInfo(dir);
if (!CopyDirectory(dir, dstDir + di.Name, bOverwrite))
{
rslt = false;
}
}
}
rslt = true;
}
catch (Exception ex)
{
string err = ex.Message;
rslt = false;
}
return rslt;
}
/// <summary>
/// 递归删除文件夹目录及文件
/// </summary>
/// <param name="baseDir"></param>
/// <returns></returns>
public static bool DeleteFolder(string baseDir)
{
var bRslt = true;
try
{
if (Directory.Exists(baseDir))
{
foreach (var dir in Directory.GetFileSystemEntries(baseDir))
{
if (File.Exists(dir))
{
File.Delete(dir);
}
else
{
bRslt = DeleteFolder(dir);
}
}
Directory.Delete(baseDir);
}
}
catch (Exception ex)
{
string er = ex.Message;
return false;
}
return bRslt;
}
#region extend
public static void CreateEntryFromAny(this ZipArchive archive, string srcName, string entryName = "")
{
var fileName = Path.GetFileName(srcName);
if (File.GetAttributes(srcName).HasFlag(FileAttributes.Directory))
{
archive.CreateEntryFromDirectory(srcName, Path.Combine(entryName, fileName));
}
else
{
archive.CreateEntryFromFile(srcName, Path.Combine(entryName, fileName), CompressionLevel.Fastest);
}
}
public static void CreateEntryFromDirectory(this ZipArchive archive, string srcDirName, string entrName = "")
{
string[] files = Directory.GetFiles(srcDirName).Concat(Directory.GetDirectories(srcDirName)).ToArray();
archive.CreateEntry(Path.Combine(entrName, Path.GetFileName(srcDirName)));
foreach (var item in files)
{
archive.CreateEntryFromAny(item, entrName);
}
}
#endregion
}

浙公网安备 33010602011771号