DotNetZip:如何解压文件,但忽略zip文件中的路径?

11

尝试将文件提取到指定文件夹,忽略压缩文件中的路径,但似乎没有方法可以实现。

考虑到其中实现的所有其他好东西,这似乎是一个相当基本的要求。

我错过了什么?

代码如下 -

using (Ionic.Zip.ZipFile zf = Ionic.Zip.ZipFile.Read(zipPath))
{
    zf.ExtractAll(appPath);
}

我正在寻找类似的解决方案,但我只想删除所有文件内容的第一步...例如/my solution/file/file1.txt变成/file/file1.txt。有任何相关资源吗? - atwellpub
请查看以下与编程有关的内容:https://dev59.com/GW025IYBdhLWcg3wIyKf @atwellpub - froeschli
4个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
25

虽然您无法为特定的Extract()ExtractAll()调用指定它,但ZipFile类有一个FlattenFoldersOnExtract字段。当设置为true时,它会将所有提取的文件平铺到一个文件夹中:

var flattenFoldersOnExtract = zip.FlattenFoldersOnExtract;
zip.FlattenFoldersOnExtract = true;
zip.ExtractAll();
zip.FlattenFoldersOnExtract = flattenFoldersOnExtract;

6
这应该是被接受的答案(DontNetZip文档)。另一个答案是一种解决方法:在提取文件之前,将其在压缩文件内重命名。 - Eric Bole-Feysot

15
您需要在解压缩之前,先删除文件名中的目录部分...
using (var zf = Ionic.Zip.ZipFile.Read(zipPath))
{
    zf.ToList().ForEach(entry =>
    {
        entry.FileName = System.IO.Path.GetFileName(entry.FileName);
        entry.Extract(appPath);
    });
}

为什么要使用zf.ToList().ForEach(entry => {...})而不是foreach (var entry in zf.Entries){}?它们之间有什么区别吗? - Joel Peltonen

2
您可以使用带有流参数的重载函数。这样,您就可以完全控制文件提取的路径。 示例:
using (ZipFile zip = new ZipFile(ZipPath))
{
     foreach (ZipEntry e in zip)
     {
        string newPath = Path.Combine(FolderToExtractTo, e.FileName);

        if (e.IsDirectory)
        {
           Directory.CreateDirectory(newPath);
        }
        else
        {
          using (FileStream stream = new FileStream(newPath, FileMode.Create))
             e.Extract(stream);
        }
     }
}

谢谢,这个方法可行!我一直在使用标记为答案的那个方法时遇到“已经添加了具有相同键的项”的错误(也许是我的错误,但无论如何)。 - Rado

1

如果有两个文件具有相同的文件名,那么这将失败。例如: files\additionalfiles\file1.txt temp\file1.txt

第一个文件将在压缩文件中重命名为file1.txt,当尝试重命名第二个文件时,会抛出异常,指示已经存在具有相同键的项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,