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

s6fujrry  于 2023-10-23  发布在  其他
关注(0)|答案(1)|浏览(175)

我使用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);

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

5ssjco0h

5ssjco0h1#

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);
     }
}

相关问题