2

Как сделать прогресс бар для распаковки архива? Использую Ionic.dll. Вот пример кода распаковки:

            using (ZipFile zip = new ZipFile(_filename))
            {
                zip.ExtractAll(_extractpath, ExtractExistingFileAction.OverwriteSilently);
                zip.Dispose();
            }
aepot
  • 49,560
Сергей
  • 425
  • 3
  • 14
  • Winforms или WPF? – aepot Sep 16 '20 at 20:15
  • Я помню делал через одну библиотеку так: Брал список файлов архива и циклом проходился по нему, делая +1 к счетчику, вот и прогресс был. Потом перешел на чуть другой способ - я изначально брал вес всех файлов и после, когда 1 файл распаковывался, я прибавлял вес файла к переменной, ну и был прогресс по типу [РаспакованоКБ]/[ВсегоКБ]. Вот собственно так и выкрутился из такой ситуации. Если ваша библиотека не имеет встроенных механизмов, то скорей всего нужно писать такой механизм, взяв за "счетчик" некую единицу (файл, размер итд). – EvgeniyZ Sep 16 '20 at 20:19
  • @aepot Winforms – Сергей Sep 16 '20 at 20:21
  • @EvgeniyZ спасибо, но там встроенное вроде бы что-то было. Я просто никак найти не могу. – Сергей Sep 16 '20 at 20:27

1 Answers1

1

Используйте ZipFile.ExtractProgress.

private async void button1_click(object sender, EventArgs e)
{
    IProgress<int> progress = new Progress<int>(p => progressBar1.Value = p);
    try
    {
        await Task.Run(() =>
        {
            int oldProgress = -1;
            using (ZipFile zip = new ZipFile(_filename))
            {
                int currentEntry = -1;
                int totalEntries = zip.Entries.Count;
                zip.ExtractProgress += (s, e) =>
                {
                    if (e.EventType == ZipProgressEventType.Extracting_BeforeExtractEntry)
                        currentEntry++;
                    else if (e.TotalBytesToTransfer > 0)
                    {
                        int newProgress = currentEntry * 100 / totalEntries + (int)(e.BytesTransferred * 100 / e.TotalBytesToTransfer / totalEntries);
                        if (newProgress != oldProgress)
                        {
                            progress.Report(newProgress);
                            oldProgress = newProgress;
                        }
                    }
                }
            zip.ExtractAll(_extractpath, ExtractExistingFileAction.OverwriteSilently);
        }
    });
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

}

Вызывать Dispose() не нужно, using вызовет его сам там, где закрывающая фигурная скобка.

aepot
  • 49,560
  • Код писал с мобильника, мог где-то опечататься. – aepot Sep 16 '20 at 20:46
  • В принципе я подправил знаки, но мне всё время кидает message box ошибку: "Попытка деления на нуль." – Сергей Sep 16 '20 at 20:48
  • @Сергей я исправил эту досадную ошибку :) – aepot Sep 16 '20 at 20:50
  • Вы просто отец русской демократии, спасибо огромное, только есть ещё одна просьба. Он показывает прогресс для каждого файла, а можно для всего архива или вы не можете с этим помочь? – Сергей Sep 16 '20 at 20:54
  • Если не хотите, я приму ответ. Ещё раз спасибо. Жду ответа. – Сергей Sep 16 '20 at 20:59
  • @Сергей ща что-нибудь придумаем, просто с мобилы медленно ищется, и решения находятся в основном костыльные. – aepot Sep 16 '20 at 21:04
  • Можно уменьшить вложенность кода на 1 уровень если использовать новую форму using: using ZipFile zip = new ZipFile(_filename); – Pavel Mayorov Sep 17 '20 at 06:07