使用进度条提取存档?

时间:2017-04-27 14:52:35

标签: c# windows

在这种情况下我如何使用进度条?

void Client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
    //System.Windows.MessageBox.Show("Update Complete!", "Message", MessageBoxButton.OK, MessageBoxImage.Information);
    Uri uri = new Uri(url);
    string filename = System.IO.Path.GetFileName(uri.AbsolutePath);
    ZipFile.ExtractToDirectory(filePathDir + "/" + filename, filePathDir);
}

编辑: @Alessandro D' Andria,但在这种情况下?:

                        WebClient wc = new WebClient();
                        Stream zipReadingStream = wc.OpenRead(url);
                        ZipArchive zip = new ZipArchive(zipReadingStream);
                        ZipFileExtensions.ExtractToDirectory(zip, filePathDir);

2 个答案:

答案 0 :(得分:5)

您可以看到ExtractToDirectory on GitHub的来源,您唯一需要做的就是传入Progress<ZipProgress>并在foreach循环中调用它。

//This is a new class that represents a progress object.
public class ZipProgress
{
    public ZipProgress(int total, int processed, string currentItem)
    {
        Total = total;
        Processed = processed;
        CurrentItem = currentItem;
    }
    public int Total { get; }
    public int Processed { get; }
    public string CurrentItem { get; }
}

public static class MyZipFileExtensions
{
    public static void ExtractToDirectory(this ZipArchive source, string destinationDirectoryName, IProgress<ZipProgress> progress)
    {
        ExtractToDirectory(source, destinationDirectoryName, progress, overwrite: false);
    }

    public static void ExtractToDirectory(this ZipArchive source, string destinationDirectoryName, IProgress<ZipProgress> progress, bool overwrite)
    {
        if (source == null)
            throw new ArgumentNullException(nameof(source));

        if (destinationDirectoryName == null)
            throw new ArgumentNullException(nameof(destinationDirectoryName));


        // Rely on Directory.CreateDirectory for validation of destinationDirectoryName.

        // Note that this will give us a good DirectoryInfo even if destinationDirectoryName exists:
        DirectoryInfo di = Directory.CreateDirectory(destinationDirectoryName);
        string destinationDirectoryFullPath = di.FullName;

        int count = 0;
        foreach (ZipArchiveEntry entry in source.Entries)
        {
            count++;
            string fileDestinationPath = Path.GetFullPath(Path.Combine(destinationDirectoryFullPath, entry.FullName));

            if (!fileDestinationPath.StartsWith(destinationDirectoryFullPath, StringComparison.OrdinalIgnoreCase))
                throw new IOException("File is extracting to outside of the folder specified.");

            var zipProgress = new ZipProgress(source.Entries.Count, count, entry.FullName);
            progress.Report(zipProgress);

            if (Path.GetFileName(fileDestinationPath).Length == 0)
            {
                // If it is a directory:

                if (entry.Length != 0)
                    throw new IOException("Directory entry with data.");

                Directory.CreateDirectory(fileDestinationPath);
            }
            else
            {
                // If it is a file:
                // Create containing directory:
                Directory.CreateDirectory(Path.GetDirectoryName(fileDestinationPath));
                entry.ExtractToFile(fileDestinationPath, overwrite: overwrite);
            }
        }
    }
}

这与

一样使用
public class YourClass
{
    public Progress<ZipProgress> _progress;

    public YourClass()
    {
        // Create the progress object in the constructor, it will call it's ReportProgress using the sync context it was constructed on.
        // If your program is a UI program that means you want to new it up on the UI thread.
        _progress = new Progress<ZipProgress>();
        _progress.ProgressChanged += Report
    }

    private void Report(object sender, ZipProgress zipProgress)
    {
        //Use zipProgress here to update the UI on the progress.
    }

    //I assume you have a `Task.Run(() => Download(url, filePathDir);` calling this so it is on a background thread.
    public void Download(string url, string filePathDir)
    {
        WebClient wc = new WebClient();
        Stream zipReadingStream = wc.OpenRead(url);
        ZipArchive zip = new ZipArchive(zipReadingStream);
        zip.ExtractToDirectory(filePathDir, _progress);
    }

    //...

答案 1 :(得分:1)

也许这样的事情对你有用:

using (var archive = new ZipArchive(zipReadingStream))
{
    var totalProgress = archive.Entries.Count;

    foreach (var entry in archive.Entries)
    {
        entry.ExtractToFile(destinationFileName); // specify the output path of thi entry

        // update progess there
    }
}

跟踪进度是一种简单的解决方法。