Невозможно распаковать файл большего размера: невозможно открыть как архив - 7-zip командная строка - PullRequest
0 голосов
/ 26 апреля 2020

У меня есть простая программа, использующая утилиту 7-Zip для командной строки , чтобы дважды разархивировать файл. При первом распаковывании файла с паролем открывается архив, в котором нет пароля. Внутренний архив затем извлекается для выявления внутренних файлов и папок.

Вот мой SevenZip.cs внутренний запечатанный класс

using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace _7zExeCmdLineDemo
{

    internal sealed class SevenZip
    {
        private const int ProcessTimeOut = 10000;
        private const int ProcessCheckListTimeOut = 300;
        private const string SEVENZIPEXEFILEPATH = "7-Zip/7z.exe";

        public static SevenZip Instance = new SevenZip();
        private List<FileModel> fileModels = new List<FileModel>();
        private bool startRead = false;
        private bool isrunning = false;

        public enum IfDuplicate
        {
            Overwrite,  // -aoa means to directly overwrite the existing file without prompting. Similar:
            Skip,       // -aos skip existing files will not be overwritten
            Rename,     // -aou If a file with the same file name already exists, it will automatically rename the released file
            RenameOld   // -aot If a file with the same file name already exists, it will automatically rename the existing file
        }

        /// <summary>
        /// unzip files
        /// <param> -aoa means to directly overwrite the existing file without prompting. There are similar: </ param>
        /// <param> -aos will not overwrite existing files if skipped </ param>
        /// <param> -aou If a file with the same file name already exists, it will automatically rename the released file </ param>
        /// <param> -aot If a file with the same file name already exists, it will automatically rename the existing file </ param>
        /// </ summary>
        /// <param name = "zipFilePath"> source file </ param>
        /// <param name = "destPath"> target folder </ param>
        /// <param name = "passKey"> password </ param>
        /// <param name = "duplicator"> Operation options when overwriting </ param>
        /// <returns> </ returns>
        public bool Extract(string zipFilePath, string destPath, string passKey, IfDuplicate duplicator = IfDuplicate.Overwrite)
        {
            var operation = string.Empty;
            switch (duplicator)
            {
                case IfDuplicate.Overwrite:
                    operation = " -aoa";
                    break;
                case IfDuplicate.Skip:
                    operation = " -aos";
                    break;
                case IfDuplicate.Rename:
                    operation = " -aou";
                    break;
                case IfDuplicate.RenameOld:
                    operation = " -aot";
                    break;
                default:
                    break;
            }

            Process process = new Process();
            bool succeeded = false;
            System.DateTime startTime = DateTime.Now;
            process.StartInfo.FileName = SEVENZIPEXEFILEPATH;
            process.StartInfo.UseShellExecute = false; // Whether to use the operating system shell to start
            process.StartInfo.RedirectStandardInput = true; // Accept input information from the calling program
            process.StartInfo.RedirectStandardOutput = true; // The output information is obtained by the calling program
            process.StartInfo.RedirectStandardError = true; // Redirect standard error output
            process.StartInfo.CreateNoWindow = true; // Do not display the program window

            if (passKey != null)
                process.StartInfo.Arguments = string.Format(@"x ""{0}"" -o""{1}"" {2} -p""{3}""", zipFilePath, destPath, operation, passKey);
            else
                process.StartInfo.Arguments = string.Format(@"x ""{0}"" -o""{1}"" {2}", zipFilePath, destPath, operation);

            process.Start(); // Start the program
            process.BeginErrorReadLine();
            process.BeginOutputReadLine();
            process.WaitForExit(ProcessTimeOut); // Wait for the program to finish and exit the process

            succeeded = (startTime.AddMilliseconds(ProcessTimeOut) > DateTime.Now);
            process.Close();
            return succeeded;
        }

    }
}

И при использовании этого в моей программе в другом месте

SevenZip.Instance .Extract(
    @"C:\Users\User\Downloads\SecuredArchive.zip",
    @"C:\Users\User\Documents", 
    "password",
    SevenZip.IfDuplicate.Overwrite
);

SevenZip.Instance .Extract(
    @"C:\Users\User\Documents\InnerArchive.zip", 
    @"C:\Users\User\Documents\InnerArchive", 
    "",
    SevenZip.IfDuplicate.Overwrite
);

Теперь это приложение хорошо работает для небольших архивов размером до 200 МБ, но при тестировании кто-то сгенерировал пакет размером 3 ГБ, и сработало только первое извлечение. И вот мой вывод консоли:

7-Zip 19.00 (x86): Copyright (c) 1999-2018 Игорь Павлов: 2019-02-21

Сканирование диска для архивов: 1 файл, 3217945253 байта (3069 МБ)

Извлечение архива: C: \ Users \ Пользователь \ Downloads \ SecuredArchive.zip

7-Zip 19.00 (x86): Авторское право (c) 1999-2018 Игорь Павлов: 2019-02-21

Сканирование диска на наличие архивов: 1 файл, 3217577691 байт (3069 МиБ)

Извлечение архива: C: \ Users \ User \ Documents \ InnerArchive.zip

Не удается открыть как архив: 1

Файлы: 0

Размер: 0

Сжатый: 0

Я все еще учусь использовать утилиты командной строки в моих приложениях c# для настольных ПК, и я был бы признателен за любые идеи о том, как это исправить, потому что я не знаю, что еще можно исправить здесь , InnerArchive.zip блокируется примерно на 2 минуты даже после того, как я закрываю приложение.

...