More .NET components

More file operations

Overwriting existing files #

When compressing or decompressing files using Add or Extract methods, use ActionOnExistingFiles argument to specify what to do when a target file already exists.

To overwrite existing files, use one of these options:

  • OverwriteAll - Overwrites all files.
  • OverwriteOlder - Overwrites files which are older than source files.
  • OverwriteDifferentSize - Overwrites files with different size.
  • OverwriteDifferentChecksum - Overwrites files with a different checksum.

Alternatively, in order not to overwrite existing files, use one of these options instead:

  • SkipAll - Skip file if the target already exists.
  • Rename - Rename files using "filename[number].extension" pattern.
  • ThrowException - Fail with an error.

Example code:

CSharp

// set desired overwrite mode according to a .config file
var action = ActionOnExistingFiles.ThrowException;
switch (ConfigurationManager.AppSettings["OverwriteMode"])
{
    case "skip":
        action = ActionOnExistingFiles.SkipAll;
        break;
    case "all":
        action = ActionOnExistingFiles.OverwriteAll;
        break;
    case "older":
        action = ActionOnExistingFiles.OverwriteOlder;
        break;
    case "size":
        action = ActionOnExistingFiles.OverwriteDifferentSize;
        break;
    case "checksum":
        action = ActionOnExistingFiles.OverwriteDifferentChecksum;
        break;
}

// extract all items with specific overwrite mode
zip.ExtractAll(@"C:\MyData\Out", action);

Auto-renaming existing files #

When compressing or decompressing multiple files using Add or Extract methods, use ActionOnExistingFiles.Rename argument to automatically rename the compressed or decompress file if the target file already exists. This will insert a number between the filename and extension ("filename[number].extension" pattern).

CSharp

// add a directory,
// auto-rename archived files if their target files already exists
// (for example, "/data/file[1].txt" might be created)
zip.Add(@"C:\MyData\*", "/data",
    0, 0, ActionOnExistingFiles.Rename);

// extract a file,
// auto-rename it if "C:\MyData\file.txt" already exists
// (for example, "C:\MyData\file[1].txt" might be created)
zip.Extract("/data/file.txt", @"C:\MyData",
    0, 0, ActionOnExistingFiles.Rename);

Tip: To specify a different new name, use ProblemDetected event instead.

Finding files #

To find a file or multiple files in a ZIP archive, use GetItems method. The GetItems method can either search a single folder with or without its subfolders, depending on specified arguments:

CSharp

ZipItemCollection items;

// find all "*.txt" files in "/data" directory only
items = zip.GetItems("/data/*.txt",
    TraversalMode.NonRecursive, ArchiveItemTypes.Files);

// find all "*.txt" files in "/data" directory and its subdirectories
items = zip.GetItems("/data/*.txt",
    TraversalMode.MatchFilesDeep, ArchiveItemTypes.Files);

Tip: Check out more information on wildcards, traversal modes and file sets.

To find a single file, use the GetItem method or ZipArchive's indexer:

CSharp

ZipItem item;

// find "/data/file1.txt"
item = zip.GetItem("/data/file1.txt");

// equivalent to above
item = zip["/data/file1.txt"];

// check whether the item exists
if (item != null)
{
    Console.WriteLine("Found: {0}", item.Path);
}

Progress reporting #

Displaying progress of both single-file and multi-file transfers is simple with TransferProgressChanged event. It keeps you updated with:

  • ProgressPercentage - percentage of the whole operation that has been completed (useful when processing multiple files).
  • CurrentFileProgressPercentage - percentage of the currently processed file.
  • Operation - current operation (add, extract, delete, listing).
  • OperationStep - current operation state (such as hierarchy retrieved, file processed or data block processed).
  • ...and more (such as files processed, files total or item paths.

Sample progress event handler:

CSharp

// register progress event handler
zip.ProgressChanged += (s, e) =>
{
    // update 'total progress' progress bar
    totalProgressBar.Value = (int)e.ProgressPercentage;

    // update 'current file progress' progress bar
    fileProgressBar.Value = (int)e.CurrentFileProgressPercentage;

    // update 'total processed bytes' label
    bytesProcessedLabel.Text = e.BytesProcessed.ToString();
};

// add some files to the ZIP archive
zip.Add(@"C:\MyData\*");

Problem handling #

When a problem occurs in Add or Extract method, your code can get notified about it using the ProblemDetected event and react accordingly. See ArchiveProblemType enum for a list of possible problems you can handle.

The event's ZipProblemDetectedEventArgs argument makes it possible to determine what is going on and choose an appropriate reaction. These are some of the properties available:

  • Exception - an exception (if any) which will be raised if the problem is not handled.
  • ProblemType - the kind of problem that has occurred.
  • Action - action to perform to handle the exception (Overwrite, Rename, ...).

This is an example of a ProblemDetected event handler that provides a custom handling of FileExists error:

  • Already-existing ".txt" files are renamed.
  • Other already-existing files are overwritten, but only if they are older than 7 days.
  • Use default behavior for all other problems.

CSharp

// register ProblemDetected event handler which is raised
// when target file already exists (besides other things)
zip.ProblemDetected += (s, e) =>
{
    // only handle 'file already exists' problem
    if (e.ProblemType != ArchiveProblemType.FileExists)
    {
        return;
    }

    // rename ".txt" files
    if (Path.GetExtension(e.ArchiveItemPath) == ".txt")
    {
        e.Action = ArchiveProblemActions.Rename;
        return;
    }

    // initialize source and target dates (use whole date granularity)
    DateTime source = e.ExternalItemLastWriteTime.Date;
    DateTime target = e.ArchiveItemLastWriteTime.Date;

    // overwrite files which are older than 7 days
    if (source > target && target < DateTime.Now.AddDays(-7))
    {
        e.Action = ArchiveProblemActions.Overwrite;
        return;
    }
};

// add some files to the ZIP archive (skip existing files by default)
zip.Add(@"C:\MyData\*", "/data", 0, 0, ActionOnExistingFiles.SkipAll);

Restoring date and time after decompression #

On most platforms, file dates/times (creation, last access and last write) are restored automatically after a successful decompression. (The only exceptions are .NET Compact Framework and Xamarin.Android, where the restoration is disabled by default.) Use ZipArchive.Options.RestoreDateTime property to specify which date/time values are to be restored:

CSharp

// restore the last write time only after decompression
zip.Options.RestoreDateTime = ItemDateTimes.LastWriteTime;

// extract files
// ...

Note: Date/time values that are not supported by the underlying file system are not restored.

Restoring attributes after decompression #

By default, Windows file attributes (such as read-only or hidden) are not restored after a successful decompression. Use ZipArchive.Options.RestoreFileAttributes property to enable restoration of file attributes.

CSharp

// restore file attributes after decompression
zip.Options.RestoreFileAttributes = true;

// extract files
// ...