【问题标题】:DotNetZip: How to extract files, but ignoring the path in the zipfile?DotNetZip:如何提取文件,但忽略 zipfile 中的路径?
【发布时间】:2010-03-09 00:16:42
【问题描述】:

尝试将文件提取到给定文件夹,忽略 zipfile 中的路径,但似乎没有办法。

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

我错过了什么?

代码是 -

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

【问题讨论】:

  • 我正在寻找类似的解决方案,但我只想删除所有文件内容的第一步...例如 /my solution/file/file1.txt 变为 /file/file1。文本文件。有这方面的资源吗?

标签: c# zip dotnetzip


【解决方案1】:

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

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

【讨论】:

  • 这应该是公认的答案 (DontNetZip doc)。另一个答案是一种解决方法:它在解压缩之前重命名 zip 中的文件。
【解决方案2】:

您需要在解压缩之前删除文件名的目录部分...

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){}?有什么区别吗?
【解决方案3】:

您可以使用将流作为参数的重载。通过这种方式,您可以完全控制将文件提取到的路径。

例子:

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

【讨论】:

  • 谢谢,这成功了!我不断收到“已添加具有相同密钥的项目”错误,其中一个标记为答案(可能是我的错误,但无论如何)。
【解决方案4】:

如果有 2 个文件名相同,这将失败。例如 文件\附加文件\file1.txt temp\file1.txt

第一个文件将在 zip 文件中重命名为 file1.txt,当尝试重命名第二个文件时会抛出异常,提示已存在具有相同密钥的项目

【讨论】:

    猜你喜欢
    • 2013-11-26
    • 2015-09-05
    • 2017-03-18
    • 2021-09-08
    • 1970-01-01
    • 1970-01-01
    • 2013-06-08
    • 1970-01-01
    相关资源
    最近更新 更多