10

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

  1. 对于 Windows 来说太长了(但在创建文件的原始操作系统中还可以)。
  2. 由于不区分大小写而“重复”

使用 DotNetZip 时,ZipFile.Read(path)只要读取存在这些问题之一的 zip 文件,调用就会出错。这意味着我什至无法尝试将其过滤掉。

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

处理读取此类文件的最佳方法是什么?

更新:

此处的示例 zip: 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.Add(TKey key, TValue value) 在 Ionic.Zip.ZipFile.ReadCentralDirectory(ZipFile zf) 在 Ionic.Zip.ZipFile.ReadIntoInstance(ZipFile zf) 2.Insert(TKey key, TValue value, Boolean add)
at System.Collections.Generic.Dictionary


解析度:

根据@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 });
            }
        }
    }
}
4

2 回答 2

8

对于这个PathTooLongException问题,我发现你不能使用DotNetZip。相反,我所做的是调用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;
    }
}
于 2015-02-05T02:28:38.207 回答
3

阅读它ZipInputStream

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

但是您可以使用ZipInputStream来读取您的ZipFile. 在这种情况下,没有集合或索引。

于 2012-05-27T00:32:12.290 回答