4

How would I delete a directory in a .zip and all the files in it (preferably using DotNetZip)?

Right now I'm running through all the files in the zip, but it doesn't work:

foreach (ZipEntry e in zip)
{
    //If the file is in the directory I want to delete
    if(e.FileName.Substring(0, 9) == "FolderName/")
    {
        zip.RemoveEntry(e.FileName);                          
    }
}

Is there a better way, if not, how would I make this work?

Greg B
  • 14,597
  • 18
  • 87
  • 141
Chris
  • 127
  • 1
  • 3
  • 8
  • -1 really? I researched for a few hours. I was just stuck on this couldn't figure it out... – Chris Mar 24 '12 at 20:25
  • 1
    Can't help but notice you retrieve a substring of length 9 chars, only to compare it to one of 11 chars, so it will *always* return false. (or is this just an example string?) – VisualMelon Jan 06 '13 at 15:14

4 Answers4

9

Here's a simple way to do this:

using (ZipFile zip = ZipFile.Read(@"C:\path\to\MyZipFile.zip"))
{
    zip.RemoveSelectedEntries("foldername/*"); // Delete folder and its contents
    zip.Save();
}

Documentation here http://dotnetzip.herobo.com/DNZHelp/Index.html

kosinix
  • 1,779
  • 1
  • 18
  • 22
7

First tought. Don't loop with foreach while removing elements from the collection.
I will try in this way

for(int x = zip.Count -1; x >= 0; x--) 
{ 
    ZipEntry e = zip[x];
    if(e.FileName.Substring(0, 9) == "FolderName/") 
        zip.RemoveEntry(e.FileName);                           
} 

However, looking at the methods of the ZipFile class, I noticed the method: SelectEntries that return a ICollection. So I think it's possible to do:
EDIT: Use overloaded version SelectEntries(string,string)

var selection = zip1.SelectEntries("*.*", "FolderName");
for(x = selection.Count - 1; x >= 0; x--)
{
    ZipEntry e = selection[x];
    zip.RemoveEntry(e.FileName);                           
}

removing the loop on all entries in the zipfile

Steve
  • 213,761
  • 22
  • 232
  • 286
  • That worked great. Why do you think mine failed? (Also, if possible, is there a way to delete the folder now?) – Chris Mar 24 '12 at 20:20
  • 3
    If you remove an item from a collection while you're enumerating through it, it's hardly surprising you'll had seen issues. This rather neat approach iterates through the collection by index, in reverse order, which avoids the issue. – tomfanning Mar 24 '12 at 20:24
  • @Chris what error did you get when you tried removing the file? – Greg B Mar 24 '12 at 20:26
  • I love you guys, Haha. Thanks a bunch! – Chris Mar 24 '12 at 20:27
  • Remove folder? Not necessary. If I remember well, removing all the "foldername/*.*" files will cause the 'folder' to disappear – Steve Mar 24 '12 at 20:27
  • @Greg "Collection was modified; enumeration operation may not be executed." – Chris Mar 24 '12 at 20:31
  • @Chris, so as you've already learned, the runtime doesn't like you changing the contents of an enumerable while you're enumerating it. If you think about it, you can imagine it could cause all kinds of weirdness. – Greg B Mar 26 '12 at 19:41
  • I get an error saying, can't apply index on Ionic.Zip.ZipEntry for line, selection[x]; – Chizl Feb 17 '13 at 20:14
  • jeez, this seems like a lot of work. There should be a RemoveDirectory method – DevDave Jul 24 '13 at 10:30
  • @TheUnrealMegashark Why don't you ask your own question? You could reference this question and tell everyone what error do you get. – Steve Aug 06 '13 at 20:44
  • Most people said you had to unzip it first... http://stackoverflow.com/questions/17904973/delete-folder-from-jar-while-treating-as-a-zip – TheUnrealMegashark Aug 07 '13 at 02:29
2

You can achieve it as follows

using (ZipArchive zip = ZipFile.Open(@"C:\path\to\MyZipFile.zip", ZipArchiveMode.Update))
{
    zip.Entries.Where(x => x.FullName.Contains("Foldername")).ToList()
        .ForEach(y =>
        {
            zip.GetEntry(y.FullName).Delete();
        });
}

Note : If all the files from the folder is deleted then the folder will be automatically removed.

Yokesh Raj
  • 21
  • 1
0

In order to delete the directory and all nested child entries, I used

var sel = (from x in zip.Entries where x.FileName.StartsWith(path, StringComparison.OrdinalIgnoreCase) select x.FileName).ToList();
foreach (var fn in sel)
{
     zip.RemoveEntry(fn);
}

Note that the path must end with a slash, like dir/subdir/

Tomas
  • 449
  • 5
  • 11