我也在寻找类似的解决方案,发现@Val 和@sDima 的解决方案对我来说更有希望。但我发现代码存在一些问题,并修复了它们以与我的代码一起使用。
和@sDima 一样,我也决定使用 Extension 为 ZipArchive 添加更多功能。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Compression;
using System.IO;
namespace ZipTest
{
public static class ZipArchiveExtensions
{
public static void CreateEntryFromAny(this ZipArchive archive, string sourceName, string entryName, CompressionLevel compressionLevel = CompressionLevel.Optimal)
{
try
{
if (File.GetAttributes(sourceName).HasFlag(FileAttributes.Directory))
{
archive.CreateEntryFromDirectory(sourceName, entryName, compressionLevel);
}
else
{
archive.CreateEntryFromFile(sourceName, entryName, compressionLevel);
}
}
catch
{
throw;
}
}
public static void CreateEntryFromDirectory(this ZipArchive archive, string sourceDirName, string entryName, CompressionLevel compressionLevel)
{
try
{
var files = Directory.EnumerateFileSystemEntries(sourceDirName);
if (files.Any())
{
foreach (var file in files)
{
var fileName = Path.GetFileName(file);
archive.CreateEntryFromAny(file, Path.Combine(entryName, fileName), compressionLevel);
}
}
else
{
//Do a folder entry check.
if (!string.IsNullOrEmpty(entryName) && entryName[entryName.Length - 1] != '/')
{
entryName += "/";
}
archive.CreateEntry(entryName, compressionLevel);
}
}
catch
{
throw;
}
}
}
}
您可以使用下面给出的简单方法尝试扩展,
class Program
{
static void Main(string[] args)
{
string filePath = @"C:\Users\WinUser\Downloads\Test.zip";
string dirName = Path.GetDirectoryName(filePath);
if (File.Exists(filePath))
File.Delete(filePath);
using (ZipArchive archive = ZipFile.Open(filePath, ZipArchiveMode.Create))
{
archive.CreateEntryFromFile( @"C:\Users\WinUser\Downloads\file1.jpg", "SomeFolder/file1.jpg", CompressionLevel.Optimal);
archive.CreateEntryFromDirectory(@"C:\Users\WinUser\Downloads\MyDocs", "OfficeDocs", CompressionLevel.Optimal);
archive.CreateEntryFromAny(@"C:\Users\WinUser\Downloads\EmptyFolder", "EmptyFolder", CompressionLevel.Optimal);
};
using (ZipArchive zip = ZipFile.OpenRead(filePath))
{
string dirExtract = @"C:\Users\WinUser\Downloads\Temp";
if (Directory.Exists(dirExtract))
{
Directory.Delete(dirExtract, true);
}
zip.ExtractToDirectory(dirExtract);
}
}
}
我试图从 .Net 框架中为扩展方法保留标准 CreateEntryFromFile 的确切行为。
要使用给出的示例代码,请添加对 System.IO.Compression.dll 和 System.IO.Compression.FileSystem.dll 的引用。
以下是这个扩展类的优点
- 递归添加文件夹内容。
- 支持空文件夹。