views:

551

answers:

3

I have a function that get a ZIP file and extract it to a directory (I use DotNetZip library.)

public void ExtractFileToDirectory(string zipFileName, string outputDirectory)
{
     ZipFile zip = ZipFile.Read(zipFileName);
     Directory.CreateDirectory(outputDirectory);
     zip.ExtractAll(outputDirectory,ExtractExistingFileAction.OverwriteSilently);
}

My ZIP file contains multiple files and directories. But I want to extract only some of these files, not all of them.

How can I make this work?

+4  A: 

You need to test each ZipEntry to see if you want to extract it:

public void ExtractFileToDirectory(string zipFileName, string outputDirectory)
{
     ZipFile zip = ZipFile.Read(zipFileName);
     Directory.CreateDirectory(outputDirectory);
      foreach (ZipEntry e in zip)
      {
        // check if you want to extract e or not
        if(e.FileName == "TheFileToExtract") 
          e.Extract(outputDirectory, ExtractExistingFileAction.OverwriteSilently);
      }
}
Oded
+4  A: 

There is a ExtractSelectedEntries method in ZipFile class. here's the method signature.

public void ExtractSelectedEntries(string selectionCriteria, string directoryPathInArchive, string extractDirectory, ExtractExistingFileAction extractExistingFile)

So in your program, you can simply extract the specified files by providing the selectionCriteria.

public void ExtractFileToDirectory(string zipFileName, string outputDirectory)
{
     ZipFile zip = ZipFile.Read(zipFileName);
     Directory.CreateDirectory(outputDirectory);
     zip.ExtractSelectedEntries("name = *.doc", "document\", outputDirectory, ExtractExistingFileAction.OverwriteSilently);
}

You can combine criteria with the conjunctions AND or OR. Using a string like "name = *.txt AND size >= 100k" for the selectionCriteria retrieves entries whose names end in .txt, and whose uncompressed size is greater than or equal to 100 kilobytes.

here are some criteria samples


criteria (Files retrieved)

name != *.xls (any file with an extension that is not .xls)

name = *.mp3 (any file with a .mp3 extension)

*.mp3 (same as above, any file with a .mp3 extension)

attributes = A (all files whose attributes include the Archive bit)

attributes != H (all files whose attributes do not include the Hidden bit)

mtime > 2009-01-01 (all files with a last modified time after January 1st, 2009)

size > 2gb (all files whose uncompressed size is greater than 2gb)


For more reference, you should read the API document alone with the library.

Mike.H
+1  A: 

You can also use LINQ to select which entries you want to extract. For example:

using (var zip = ZipFile.Read(ArchiveToRead))
{
    var selection = from e in zip.Entries
        where System.IO.Path.GetFileName(e.FileName).StartsWith("C")
        select e;

    foreach (var e in selection)
        e.Extract(extractDir);
}

Of course you can use whatever query criteria you want in the where clause.

Cheeso