如何使用太长/重复的路径解压缩Zip文件

时间:2012-05-20 21:33:30

标签: c# zipfile dotnetzip

在Windows中解压缩文件时,我偶尔会遇到路径问题

  1. 对于Windows来说太长了(但在创建该文件的原始操作系统中没问题)。
  2. 由于不区分大小写而“重复”
  3. 使用DotNetZip时,只要读取其中一个问题的zip文件,ZipFile.Read(path)调用就会消失。这意味着我甚至无法尝试过滤掉它。

    using (ZipFile zip = ZipFile.Read(path))
    {
        ...
    }
    

    处理阅读这类文件的最佳方法是什么?

    更新:

    此处的拉链示例: https://github.com/MonoReports/MonoReports/zipball/master

    重复: https://github.com/MonoReports/MonoReports/tree/master/src/MonoReports.Model/DataSourceType.cs https://github.com/MonoReports/MonoReports/tree/master/src/MonoReports.Model/DatasourceType.cs

    以下是关于例外的更多细节:

      

    Ionic.Zip.ZipException:无法读取它作为ZipFile
      ---> System.ArgumentException:>已添加具有相同键的项目     在System.ThrowHelper.ThrowArgumentException(ExceptionResource资源)
        在System.Collections.Generic.Dictionary 2.Insert(TKey key, TValue value, Boolean add)
    at System.Collections.Generic.Dictionary
    2.添加(TKey键,TValue值)
        在Ionic.Zip.ZipFile.ReadCentralDirectory(ZipFile zf)
        在Ionic.Zip.ZipFile.ReadIntoInstance(ZipFile zf)

    解决:

    基于@ Cheeso的建议,我可以阅读流中的所有内容,避免重复的内容以及路径问题:

    //using (ZipFile zip = ZipFile.Read(path))
    using (ZipInputStream stream = new ZipInputStream(path))
    {
        ZipEntry e;
        while( (e = stream.GetNextEntry()) != null )
        //foreach( ZipEntry e in zip)
        {
            if (e.FileName.ToLower().EndsWith(".cs") ||
                e.FileName.ToLower().EndsWith(".xaml"))
            {
                //var ms = new MemoryStream();
                //e.Extract(ms);
                var sr = new StreamReader(stream);
                {
                    //ms.Position = 0;
                    CodeFiles.Add(new CodeFile() { Content = sr.ReadToEnd(), FileName = e.FileName });
                }
            }
        }
    }
    

2 个答案:

答案 0 :(得分:8)

对于PathTooLongException问题,我发现您无法使用DotNetZip。相反,我所做的是调用command-line version of 7-zip;这是奇迹。

public static void Extract(string zipPath, string extractPath)
{
    try
    {
        ProcessStartInfo processStartInfo = new ProcessStartInfo
        {
            WindowStyle = ProcessWindowStyle.Hidden,
            FileName = Path.GetFullPath(@"7za.exe"),
            Arguments = "x \"" + zipPath + "\" -o\"" + extractPath + "\""
        };
        Process process = Process.Start(processStartInfo);
        process.WaitForExit();
        if (process.ExitCode != 0) 
        {
            Console.WriteLine("Error extracting {0}.", extractPath);
        }
    }
    catch (Exception e)
    {
        Console.WriteLine("Error extracting {0}: {1}", extractPath, e.Message);
        throw;
    }
}

答案 1 :(得分:3)

使用ZipInputStream读取它。

ZipFile类使用文件名作为索引来保存集合。重复的文件名会破坏该模型。

但是你可以使用ZipInputStream来读取你的zip文件。在这种情况下没有集合或索引。