Как обрабатывать распаковку ZipFile с помощью слишком длинных / дублированных путей

При разархивировании файлов в Windows у меня иногда возникают проблемы с путями

that are too long for Windows (but okay in the original OS that created the file). that are "duplicate" due to case-insensitivity

Используя DotNetZip,ZipFile.Read(path) При чтении zip-файлов с одной из этих проблем вызов будет сорван. Это означает, что я даже не могу отфильтровать его.

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

Каков наилучший способ справиться с чтением таких файлов?

Updated:

Пример почтового индекса здесь: 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: Cannot read that as a ZipFile
---> System.ArgumentException: An > item with the same key has already been added.
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary2.Insert(TKey key, TValue value, Boolean add)<br> at System.Collections.Generic.Dictionary2.Add(TKey key, TValue value)
at Ionic.Zip.ZipFile.ReadCentralDirectory(ZipFile zf)
at Ionic.Zip.ZipFile.ReadIntoInstance(ZipFile zf)

Resolution:

Основываясь на предложении @ 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 });
            }
        }
    }
}
 gameweld22 мая 2012 г., 00:09
Я обновил вопрос, чтобы он был более общим: и дубликаты файлов, и длинные пути являются проблемой и включают примеры.
 yamen21 мая 2012 г., 04:49
Можете показать ошибку? Это путь внутри файла? Расположение целевого файла слишком длинное?
 SimpleVar21 мая 2012 г., 01:59
Это файл .zip или .gz?
 gameweld21 мая 2012 г., 02:53
.zip (специально для загрузки с github zipfile)

Ответы на вопрос(2)

Решение Вопроса

Класс ZipFile хранит коллекцию, используя имя файла в качестве индекса. Двойные имена файлов ломают эту модель.

Но вы можете использовать ZipInputStream для чтения в вашем zipfile. В этом случае нет коллекции или индекса.

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;
    }
}
 27 дек. 2016 г., 00:47
Спасибо @sigil, в соответствии сthis Вы правы, я обновил свой ответ.
 27 дек. 2016 г., 00:41
Arguments строка неверна; так должно бытьArguments = "x \"" + zipPath + "\" -o \"" + extractPath + "\"" (обратите внимание, что междуo переключатель иextractPath.
 16 мар. 2017 г., 14:46
Хороший ответ. Также, чтобы избежать остановки процесса с подсказкой о переопределении существующих, вы можете добавить-y к аргументам
 08 февр. 2015 г., 18:39
На самом деле это самое простое решение, которое я нашел. На момент написания этого комментария было бы полезно знать, что 7za.exe находится в 7-zip загрузках с дополнительным 7-zip: .... & quot; в описании. (7-zip.org/download.html)

Ваш ответ на вопрос