无法将空文件夹添加到 zip 存档中

问题描述 投票:0回答:1

我使用 C# .net 4.0。我使用以下方法创建 Zip 存档:

    internal void compressZip(string folderPath)
    {
        if (!Directory.Exists(folderPath))
        {
            MessageBox.Show("Directory not exist: " + folderPath);
            return;
        }

        byte[] startBuffer = { 80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        File.WriteAllBytes(folderPath + ".zip", startBuffer);

        var shellAppType = Type.GetTypeFromProgID("Shell.Application");
        var oShell = Activator.CreateInstance(shellAppType);
        var sourceFolder = (Shell32.Folder)shellAppType.InvokeMember("NameSpace", System.Reflection.BindingFlags.InvokeMethod, null, oShell, new object[] { folderPath });
        var destinationFile = (Shell32.Folder)shellAppType.InvokeMember("NameSpace", System.Reflection.BindingFlags.InvokeMethod, null, oShell, new object[] { folderPath + ".zip" });
        destinationFile.CopyHere(sourceFolder.Items(), 4 | 16);
    }

但是当我尝试压缩空文件夹时出现问题。它写的是“无法将空文件夹添加到 zip 存档中”。为什么?

如果我将 CopyHere 更改为:

destinationFile.CopyHere(sourceFolder, 4 | 16);

它工作正常。但它在存档中创建父文件夹。如何使用没有父文件夹的空文件夹创建存档?

c# winforms .net-4.0 visual-studio-2019
1个回答
0
投票

sourceFolder.Items() 包含文件夹中的所有文件和子文件夹。

sourceFolder 复制的整个文件夹,包括父文件夹。

您可以使用以下代码来压缩文件,父文件夹可以省略,空文件夹不省略:

    internal void CompressZip(string folderPath)
    {
        if (!Directory.Exists(folderPath))
        {
            MessageBox.Show("Directory not exist: " + folderPath);
            return;
        }

        string zipFilePath = folderPath + ".zip";

        using (FileStream zipToCreate = new FileStream(zipFilePath, FileMode.Create))
        {
            using (ZipArchive archive = new ZipArchive(zipToCreate, ZipArchiveMode.Create))
            {
                CompressFolder(folderPath, archive, "");
            }
        }
    }

    private void CompressFolder(string folderPath, ZipArchive archive, string parentFolder)
    {
        foreach (var file in Directory.GetFiles(folderPath))
        {
            string entryName = Path.Combine(parentFolder, Path.GetFileName(file));
            archive.CreateEntryFromFile(file, entryName);
        }

        foreach (var subFolder in Directory.GetDirectories(folderPath))
        {
            string entryName = Path.Combine(parentFolder, Path.GetFileName(subFolder));
            var folderEntry = archive.CreateEntry(entryName + "/");
            // Recursively add files and subfolders in the current subfolder
            CompressFolder(subFolder, archive, entryName);
        }
    }

此时我的Test文件夹下有空文件夹和aaa.txt,通过上面的代码生成了Test.zip

第二次更新:

非常抱歉,我的电脑没有.net 4.0,所以测试过程中出现了一些偏差。我在寻找其他方法的过程中发现了ShareZipLip 0.86.0。它似乎不需要 .net 版本。您可以尝试以下代码:

internal void CompressZip(string folderPath)
{
     if (!Directory. Exists(folderPath))
     {
         MessageBox. Show("Directory not exist: " + folderPath);
         return;
     }

     string zipFilePath = folderPath + ".zip";

     using (FileStream fsOut = File. Create(zipFilePath))
     {
         using (ZipOutputStream zipStream = new ZipOutputStream(fsOut))
         {
             zipStream.SetLevel(9); // Compression level, 0-9, 9 means the highest compression

             CompressFolder(folderPath, zipStream, "");
         }
     }
}

private void CompressFolder(string folderPath, ZipOutputStream zipStream, string parentFolder)
{
     string[] files = Directory. GetFiles(folderPath);
     foreach (string file in files)
     {
         string entryName = Path. Combine(parentFolder, Path. GetFileName(file));
         ZipEntry newEntry = new ZipEntry(entryName);
         zipStream.PutNextEntry(newEntry);

         using (FileStream fs = File. OpenRead(file))
         {
             byte[] buffer = new byte[4096];
             StreamUtils. Copy(fs, zipStream, buffer);
         }

         zipStream. CloseEntry();
     }

     string[] subFolders = Directory. GetDirectories(folderPath);
     foreach (string subFolder in subFolders)
     {
         string entryName = Path. Combine(parentFolder, Path. GetFileName(subFolder));
         ZipEntry newEntry = new ZipEntry(entryName + "/");
         zipStream.PutNextEntry(newEntry);
         CompressFolder(subFolder, zipStream, entryName);
     }
}
© www.soinside.com 2019 - 2024. All rights reserved.