【问题标题】:C# to unzip all nested zips in a directory while preserving file structureC# 在保留文件结构的同时解压缩目录中的所有嵌套 zip
【发布时间】:2020-12-18 13:54:15
【问题描述】:

我正在尝试解压缩一个目录中的所有 zip,其中有时包含多层嵌套的 zip。我还想在提取的版本中保留原始的 zip 嵌套结构。我可以用一层拉链做我想做的事,但不能用于嵌套拉链或子文件夹内的拉链。

例如,我想将起始文件夹中的所有内容都变成这样:

[Starting Folder]
-Zip1.zip
--NestedZip1.zip
---text1.txt
--NestedZip2.zip
---text2.txt
-Zip2.zip
--[Subfolder1]
---Zip3.zip
----text3.txt
---Zip4.zip
----text4.txt

然后将所有内容提取到同一起始目录中的文件夹中:

[Starting Folder]
[Extracted Folder]
-Zip1 (folder)
--NestedZip1 (folder)
---text1.txt
--NestedZip2 (folder)
---text2.txt
-Zip2 (folder)
--[Subfolder1]
---Zip3 (folder)
----text3.txt
---Zip4 (folder)
----text4.txt

现在我正在使用它来解压缩 MyGlobals.finalPathForWork(这是起始目录)中的所有文件,它可以工作,但只解压缩一层拉链。我需要它以某种方式再次运行,以防第一层拉链中有拉链。

        public static void MyMethod3()
    {
        string startPath = MyGlobals.finalPathForWork;
        string extractPath = MyGlobals.finalPathForWork + @"\\Extracted\";
        Directory.GetFiles(startPath, "*.zip", SearchOption.AllDirectories).ToList()
            .ForEach(zipFilePath =>
            {
                var extractPathForCurrentZip = Path.Combine(extractPath, Path.GetFileNameWithoutExtension(zipFilePath));
                if (!Directory.Exists(extractPathForCurrentZip))
                {
                    Directory.CreateDirectory(extractPathForCurrentZip);
                }
                ZipFile.ExtractToDirectory(zipFilePath, extractPathForCurrentZip);
            });
    }

我尝试过应用/组合以下内容:How to unzip multi layered zip files in C#

public static void ExtractFile(string baseZipPath, string extractPath)
{
        if (!Directory.Exists(extractPath))
            Directory.CreateDirectory(extractPath);

        ZipFile.ExtractToDirectory(baseZipPath, extractPath);
        string[] nestedZipDirectories = System.IO.Directory.GetFiles(extractPath, "*.zip");
        foreach (var nestedZipDirectory in nestedZipDirectories)
        {
            ZipFile.ExtractToDirectory(nestedZipDirectory, extractPath);
        }
}

static void Main(string[] args)
{
    ExtractFile(@"c:\myfolder\grandfather.zip", @"c:\myfolder2");
}

是否有另一种方法可以通过所有子文件夹和嵌套的 zip 文件循环搜索/解压缩过程?或者上面的其他解决方案是否应该有效,而我必须错误地合并它?

【问题讨论】:

    标签: c# unzip


    【解决方案1】:

    这是递归的经典用例。
    注意代码中的 cmets:

    public static void ExtractFile(string zipFilePath, string extractPath)
    {
        // If directory already exist, CreateDirectory does nothing
        Directory.CreateDirectory(extractPath); 
    
        // Extract current zip file
        ZipFile.ExtractToDirectory(zipFilePath, extractPath);
    
        // Enumerate nested zip files
        var nestedZipFiles = Directory.EnumerateFiles(extractPath, "*.zip");
    
        // iterate the enumerator
        foreach (var nestedZipFile in nestedZipFiles)
        {    
            // Get the nested zip full path + it's file name without the ".zip" extension
            // I.E this "C:\users\YourUserName\Documents\SomeZipFile.Zip" - turns to this: "C:\users\YourUserName\Documents\SomeZipFile".
            var nestedZipExtractPath = Path.Combine(Path.GetDirectoryName(nestedZipFile), Path.GetFileNameWithoutExtension(nestedZipFile));
    
            // extract recursively
            ExtractFile(nestedZipFile, nestedZipExtractPath);
        }
    }
    

    【讨论】:

    • 谢谢。多亏了您的 cmets,我可以知道发生了什么,但是如何将它传递给我想在其中运行它的目录?现在,我传递给我的任何方法的唯一内容是“MyGlobals.finalPathForWork”——这是我希望这个进程运行的目录。那是存储在 MyGlobals 类中的字符串。对不起,如果这很明显,或者我使用了错误的术语。我非常缺乏经验。
    • 您通过使用主 zip 文件的路径和要将其解压缩到的目录的路径来调用此方法来启动该过程。假设MyGlobals.finalPathForWork中的字符串是目标目录的路径,MyGlobals.ZipFilePath是主zip文件的路径,你做<ContainingType>.ExtractFile(MyGlobals.finalPathForWork, MyGlobals.ZipFilePath);(一定要把<ContainingType>替换成包含这个方法的类型的名字)。
    • 如果我能提供的只是起始/主/根目录,它还能工作吗?我可以给它起始目录和提取目录(这只是起始目录+"\Extracted")但没有baseZipPath,因为我不知道里面有什么拉链——只有起始目录:@987654328 @。我想在那个文件夹上运行它。还是我只是从该文件夹中随机选择一个 zip 并发送它?
    • 当我尝试将存储所有 zip 文件的起始目录和提取的目录(只是起始目录 + \Extracted)传递给它时 - 我在 Directory.EnumerateFiles(extractPath, "*.zip"); 上收到错误消息:“无法将类型 'System.Collections.Generic.IEnumerable' 隐式转换为 'string[]'。存在显式转换(您是否缺少演员表?)“
    • 是的,好吧,至于你的第一个问题 - 答案是否定的。如果您只提供目录的路径,则需要调整代码以搜索该目录中的所有 zip 文件。对于您的第二个问题,这是答案的错字 - string[] nestedZipFiles 应该是 var nestedZipFiles - 我已经编辑了。
    猜你喜欢
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    • 2023-03-16
    相关资源
    最近更新 更多