Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle unzipping ZipFile with paths that are too long/duplicate

When unzipping files in Windows, I'll occasionally have problems with paths

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

Using DotNetZip, the ZipFile.Read(path) call will crap out whenever reading zip files with one of these problems. Which means I can't even try filtering it out.

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

What is the best way to handle reading those sort of files?

Updated:

Example zip from here: https://github.com/MonoReports/MonoReports/zipball/master

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

Here is more detail on the exception:

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)
at System.Collections.Generic.Dictionary
2.Add(TKey key, TValue value)
at Ionic.Zip.ZipFile.ReadCentralDirectory(ZipFile zf)
at Ionic.Zip.ZipFile.ReadIntoInstance(ZipFile zf)

Resolution:

Based on @Cheeso's suggestion, I can read everything from the stream, those avoiding duplicates, and path issues:

//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 });
            }
        }
    }
}
like image 987
gameweld Avatar asked May 20 '12 21:05

gameweld


People also ask

How do I extract a zip file if the path is too long?

If you see this error there are several solutions: 1) Instead of right clicking on the file to extract it, left click on the file to enter the zip directly. Then look for long folder names and make them shorter. Then close the zip file and extract it again.

What does error 0x80010135 path too long mean?

Error 0x80010135: Path too long is reported. Usually this error is caused when you use Windows Explorer or WinZip to extract files and it encounters a file path that exceeds the maximum character limit. To resolve this problem, you may use a decompression utility such as 7-Zip, that can handle long file paths.

What is the fastest way to extract a large zip file?

Right-click the file you want to zip, and then select Send to > Compressed (zipped) folder. Open File Explorer and find the zipped folder. To unzip the entire folder, right-click to select Extract All, and then follow the instructions.

Can you extract a ZIP file multiple times?

Extract Multiple Zip Files. Have you ever been sent a lot of zip files you needed to unzip? WinZip allows you to extract multiple files at the same time making your job a lot easier.


1 Answers

For the PathTooLongException problem, I found that you can't use DotNetZip. Instead, what I did was invoke the command-line version of 7-zip; that works wonders.

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;
    }
}
like image 92
Maria Ines Parnisari Avatar answered Sep 22 '22 06:09

Maria Ines Parnisari