guyr79
guyr79

Reputation: 167

How to recursively explore for zip file contents without extraction

I want to write a function that will explore a ZIP file and will find if it contains a .png file. Problem is, it should also explore contained zip files that might be within the parent zip (also from other zip files and folders).

as if it is not painful enough, the task must be done without extracting any of the zip files, parent or children.

I would like to write something like this (semi pseudo):

public bool findPng(zipPath) {
    bool flag = false;
    using (ZipArchive archive = ZipFile.OpenRead(zipPath))    
    {
       foreach (ZipArchiveEntry entry in archive.Entries)
       {
         string s = entry.FullName;
         if (s.EndsWith(".zip")) 
         {
             /* recoursively calling findPng */
             flag = findPng(s);
             if (flag == true)
             return true;
         }
         /* same as above with folders within the zip */

         if((s.EndsWith(".png")
           return true;
       }
       return false
   }
}

Problem is, I can't find a way to explore inner zip files without extracting the file, which is a must prerequisite (to not extract the file).

Thanks in advance!

Upvotes: 2

Views: 2278

Answers (1)

ProgrammingLlama
ProgrammingLlama

Reputation: 38757

As I pointed to in the question I marked yours basically as a duplicate off, you need to open the inner zip file.

I'd change your "open from file" method to be like this:

// Open ZipArchive from a file
public bool findPng(zipPath) {
    using (ZipArchive archive = ZipFile.OpenRead(zipPath))    
    {
        return findPng(archive);
    }
}

And then have a separate method that takes a ZipArchive so that you can call it recursively by opening the entry as a Stream as demonstrated here

// Search ZipArchive for PNG
public bool findPng(ZipArchive archive)
{
    foreach (ZipArchiveEntry entry in archive.Entries)
    {
         string s = entry.FullName;
         if (s.EndsWith(".zip")) 
         {
             // Open inner zip and pass to same method
             using (ZipArchive innerArchive = new ZipArchive(entry.Open()))
             {
                 if (findPng(innerArchive))
                    return true;
             }
         }
         /* same as above with folders within the zip */

         if(s.EndsWith(".png"))
           return true;
       }
       return false;
    }
}

As an optimisation, I would recommend checking all of the filenames before handling nested zip files.

Upvotes: 3

Related Questions