如何创建只包含特定扩展名的zip归档文件
本文关键字:扩展名 zip 归档文件 包含特 何创建 创建 | 更新日期: 2023-09-27 18:09:56
我需要创建一个zip存档,它应该只包含某些扩展名的文件,但我需要保存原始目录的结构。
例如,我有一个结构如下的目录:dir'
sub_dir1'
1.exe
sub_dir_2'
1.txt
1.exe
1.txt
1.bat
和我需要得到一个档案与以下结构(只有。exe和。bat文件):
dir'
sub_dir1'
1.exe
sub_dir_2'
1.exe
1.bat
我知道如何通过目录找到这些文件。getfile方法:
var ext = new List<string> {".exe", ".bat"};
var myFiles = Directory.GetFiles(dir, "*.*", SearchOption.AllDirectories)
.Where(s => ext.Any(e => s.EndsWith(e));
但是我不知道如何保存存档的结构。
我怎样才能达到这样的行为?
您可以从所有子目录中获取所有扩展名为。exe和。bat的文件,例如:
IList<FileInfo> info = null;
DirectoryInfo dirInfo = new DirectoryInfo(path);
info = dirInfo
.GetFiles("*.*", SearchOption.AllDirectories)
.Where( f => f.Extension
.Equals(".exe", StringComparison.CurrentCultureIgnoreCase)
|| f.Extension
.Equals(".bat", StringComparison.CurrentCultureIgnoreCase)
)
.ToList()
;
然后基于这个FileInfo列表,你可以创建你的zip和文件夹结构。您可以在这里找到文件信息的详细信息
System.IO.Directory.GetFiles("C:''temp", "*.exe", SearchOption.AllDirectories);
将返回一个包含完整文件路径的数组,如:
[C:'temp'dir1'app1.exe]
[C:'temp'dir2'subdir1'app2.exe]
[C:'temp'dir3'subdir2'subdir3'app3.exe]
因此,使用ZipArchive将这些文件放入zip容器中不会有任何麻烦。因为此方法将在zip中创建相同的目录结构。但是,您应该删除开头的C:'
。
我相信这个非常好的教程将帮助您做到这一点。
如果你想在目标zip中保持空文件夹,也许你必须使用ZipArchive.CreateEntry
方法来做。在此演示中,作者仅使用ZipArchive. CreateEntryFromFile
方法从文件路径归档文件。
您也可以使用DotNetZip库来解决您的问题。例如,下面的代码片段可以帮助您。使用CreateZip()
方法。简而言之,您应该找到用于写入存档GetFileNames()
的文件,并使用CreateZipFromFileNames()
创建zip文件:
/// <summary>
/// Create zip archive from root directory with search patterns
/// </summary>
/// <param name="rootDirectory">Root directory</param>
/// <param name="searchPatterns">Search patterns</param>
/// <param name="zipFileName">Zip archive file name</param>
public static void CreateZip(string rootDirectory, List<string> searchPatterns, string zipFileName)
{
var fileNames = GetFileNames(rootDirectory, searchPatterns, true);
CreateZipFromFileNames(rootDirectory, zipFileName, fileNames);
}
/// <summary>
/// Get file names filtered by search patterns
/// </summary>
/// <param name="rootDirectory">Root diirectory</param>
/// <param name="searchPatterns">Search patterns</param>
/// <param name="includeSubdirectories">True if it is included files from subdirectories</param>
/// <returns>List of file names</returns>
private static IEnumerable<string> GetFileNames(string rootDirectory, List<string> searchPatterns, bool includeSubdirectories)
{
var foundFiles = new List<string>();
var directoriesToSearch = new Queue<string>();
directoriesToSearch.Enqueue(rootDirectory);
// Breadth-First Search
while (directoriesToSearch.Count > 0)
{
var path = directoriesToSearch.Dequeue();
foreach (var searchPattern in searchPatterns)
{
foundFiles.AddRange(Directory.EnumerateFiles(path, searchPattern));
}
if (includeSubdirectories)
{
foreach (var subDirectory in Directory.EnumerateDirectories(path))
{
directoriesToSearch.Enqueue(subDirectory);
}
}
}
return foundFiles;
}
/// <summary>
/// Create zip archive from list of file names
/// </summary>
/// <param name="rootDirectroy">Root directory (for saving required structure of directories)</param>
/// <param name="zipFileName">File name of zip archive</param>
/// <param name="fileNames">List of file names</param>
private static void CreateZipFromFileNames(string rootDirectroy, string zipFileName, IEnumerable<string> fileNames)
{
var rootZipPath = Directory.GetParent(rootDirectroy).FullName;
using (var zip = new ZipFile(zipFileName))
{
foreach (var filePath in fileNames)
{
var directoryPathInArchive = Path.GetFullPath(Path.GetDirectoryName(filePath)).Substring(rootZipPath.Length);
zip.AddFile(filePath, directoryPathInArchive);
}
zip.Save();
}
}
使用示例:
CreateZip("dir", new List<string> { "*.exe", "*.bat" }, "myFiles.zip");
@Didgeridoo说:DotNetZip。但是DotNetZip可以让您更具表现力。例如:
string cwd = Environment.CurrentDirectory ;
try
{
Environment.CurrentDirectory = @"c:'root'of'directory'tree'to'be'zipped" ;
using ( ZipFile zipfile = new ZipFile() )
{
zipfile.AddSelectedFiles( "name = *.bat OR name = *.exe" , true ) ;
zipfile.Save( @"c:'foo'bar'my-archive.zip") ;
}
}
finally
{
Environment.CurrentDirectory = cwd ;
}
编辑注: DotNetZip曾经生活在Codeplex。Codeplex已关闭。旧的存档文件在Codeplex上仍然可用。看起来代码已经迁移到Github:
- https://github.com/DinoChiesa/DotNetZip。看起来是原作者的repo。
- https://github.com/haf/DotNetZip.Semverd。这看起来是当前维护的版本。它也可以通过Nuget在https://www.nuget.org/packages/DotNetZip/ 获得。