Example #1
0
        /// <summary>
        /// Разархивация
        /// </summary>
        /// <param name="source">Файл архива</param>
        /// <param name="output">Каталог для разархивации</param>
        /// <param name="password">Пароль к архиву(пусто или null в случае отсутствия)</param>
        public void Decompress(string source, string output, string password)
        {
            CompressorOption option = new CompressorOption();

            processors.Clear();
            FileStream   fs            = null;
            BinaryReader br            = null;
            Header       unpack_header = new Header();

            try
            {
                using (fs = new FileStream(source, FileMode.Open, FileAccess.Read))
                {
                    using (br = new BinaryReader(fs))
                    {
                        //Считаем тип архива
                        PrimeArchiverType type = (PrimeArchiverType)br.ReadByte();
                        //Добавляем процессоры для обработки файлов исходя из типа архива
                        //ВАЖНО! Порядок добавления должен быть обратным порядку добавления в методе сжатия
                        if ((type & PrimeArchiverType.Password) == PrimeArchiverType.Password)
                        {
                            EncryptFile ef = new EncryptFile();
                            ef.SetKey(password);
                            processors.Add(ef);
                        }
                        if ((type & PrimeArchiverType.NoCompression) != PrimeArchiverType.NoCompression)
                        {
                            processors.Add(new CompressFile());
                        }
                        //Считаем длину обработанного заголовка
                        byte[] header_length_arr = br.ReadBytes(sizeof(int));
                        //Считываем обработанный заголовок
                        byte[] header_arr = br.ReadBytes(BitConverter.ToInt32(header_length_arr, 0));
                        //Пишем заголовок в файл
                        string         header_path = TempNameGenerator.GenerateTempNameFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "header.dat"));
                        HeaderItemPath hip_header  = new HeaderItemPath();
                        hip_header.UpdateCurrentPath(header_path);
                        using (FileStream fw = new FileStream(header_path, FileMode.Create, FileAccess.Write))
                        {
                            transfer.Transfer(new MemoryStream(header_arr), fw);
                        }
                        //Преобразуем заголовок через процессоры
                        foreach (IProcessFile processor in processors)
                        {
                            hip_header.UpdateCurrentPath(processor.BackProcessExecute(hip_header.GetCurrentPath()));
                        }
                        //Парсим заголовок
                        using (FileStream fr = new FileStream(hip_header.GetCurrentPath(), FileMode.Open, FileAccess.Read))
                        {
                            byte[] header_body = new byte[fr.Length];
                            int    count       = fr.Read(header_body, 0, (int)fr.Length);
                            unpack_header.Parse(header_body);
                        }
                        hip_header.ClearTemporeryPathes(true);
                        //Обрабатываем распарсенный заголовок
                        foreach (HeaderItem item in unpack_header.Items)
                        {
                            //Если объект является каталогом, просто создаем его, в теле архива записей нет
                            if (item.Length == 0)
                            {
                                string full_path = Path.Combine(output, item.RelativePath);
                                Process(full_path);
                                Operations.CreateDirectory(full_path);
                            }
                            //Если объект является файлом
                            else
                            {
                                string full_path = Path.Combine(output, item.RelativePath);
                                Process(full_path);
                                //Считываем тело файла
                                byte[] file_body = br.ReadBytes((int)item.Length);
                                //Записываем в файл
                                HeaderItemPath hip_file = new HeaderItemPath();
                                hip_file.UpdateCurrentPath(TempNameGenerator.GenerateTempNameFromFile(full_path));
                                using (FileStream fw = new FileStream(hip_file.GetCurrentPath(), FileMode.Create, FileAccess.Write))
                                {
                                    transfer.Transfer(new MemoryStream(file_body), fw);
                                }
                                //Преобразуем через процессоры
                                foreach (IProcessFile processor in processors)
                                {
                                    hip_file.UpdateCurrentPath(processor.BackProcessExecute(hip_file.GetCurrentPath()));
                                }
                                //Сохраняем в конечный файл
                                Operations.MoveFile(hip_file.GetCurrentPath(), full_path);
                                hip_file.RemoveLast();
                                //Удаляем временные файлы
                                hip_file.ClearTemporeryPathes(true);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Process(ex.Message);
            }
            finally
            {
                if (br != null)
                {
                    br.Close();
                }
                if (fs != null)
                {
                    fs.Close();
                }
            }
        }