Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
0 / 0 / 0
Регистрация: 12.09.2017
Сообщений: 36
1

Объединение частей GZip архива

28.06.2018, 10:29. Показов 2023. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Например есть две части GZip архива, я их объединяю в одну архивную часть. Размер получается верный, но если распаковывать стандартным образом собранный воедино архив, то на выходе получаю разархивированной только самую первую часть архива. Все равно что, если бы я не собирал части архива в один общий архив, а просто разархивировал первую часть.


Самое интересное, что если распаковать такой архив винраром, то все отлично.

В чем проблема?

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// метод слияния частей архивов
        void JoinCompressFiles()
        {
              List<byte> buffer = new List<byte>();
              foreach (var name in sortFileNameList)
              {
                  using (FileStream fsWrite = new FileStream(pathToCompressFolder + fileName + ".gz", FileMode.Append, FileAccess.Write))
                  {
                      buffer.AddRange(File.ReadAllBytes(pathToCompressFolder + name));
                      fsWrite.Write(buffer.ToArray(), 0, buffer.Count);
                      buffer.Clear();
                      File.Delete(pathToCompressFolder + name);
                  }
              }
        }
 
//метод распаковки архива
        void StartDecompress(object name)
        {
            try
            {
                byte[] tempBuffer = File.ReadAllBytes(pathToCompressFolder + name.ToString());
                using (FileStream fsRead = new FileStream(pathToCompressFolder + name.ToString(), FileMode.Open, FileAccess.Read))
                {
                    using (FileStream fsWrite = new FileStream(pathToDecompressFolder + fileName, FileMode.Create, FileAccess.Write))
                    {
                        using (GZipStream gzipStream = new GZipStream(fsRead, CompressionMode.Decompress))
                        {
                            int p;
                            while ((p = gzipStream.Read(tempBuffer, 0, tempBuffer.Length)) > 0)
                            {
                                fsWrite.Write(tempBuffer, 0, p);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("error" + ex);
            }
        }
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.06.2018, 10:29
Ответы с готовыми решениями:

Неправильное магическое число в заголовке GZip. Передача должна идти в поток GZip
Добрый день, пытаюсь написать свой мини-архиватор. Задача заключается в использовании только...

Объединение частей строк
Люди, помогите пожалуйста, нужно отладить код! Даны два числа: N1 и N2, и две строки: S1 и S2....

Объединение частей файла
Большие файлы на файлообменниках размещены частями до 100 Мб. Подскажите, пожалуйста, как после...

Разделение текстового файла на переменное количество частей и перемещение этих частей
С Вашей помощью у меня получается создать папки с плейлистами @echo off setlocal...

10
Эксперт .NET
10566 / 6490 / 1506
Регистрация: 25.05.2015
Сообщений: 19,659
Записей в блоге: 14
28.06.2018, 10:43 2
Цитата Сообщение от retah Посмотреть сообщение
buffer.AddRange(File.ReadAllBytes(pathToCompressFolder + name));
Никуда не годный способ. При большом размере файла вам ОЗУ не хватит.

Цитата Сообщение от retah Посмотреть сообщение
я их объединяю в одну архивную часть
Нет такого стандартного метода. Т.е. от того, что вы слили файлы архивов в один файл, он не стал файлом одного архива.
В GZip надо паковать один файл и всё. Алгоритмы сборки и разборки кучи файлов, либо одного файла на части, должны быть понятны и запаковывающей программе, и распаковывающей.
В линуксах, например, распространены архивы *.tar.gz. Где tar пакует каталоги файлов в единый файл, а gzip сжимает уже этот единый файл.

Цитата Сообщение от retah Посмотреть сообщение
если распаковывать стандартным образом собранный воедино архив, то на выходе получаю разархивированной только самую первую часть архива.
Потому что формат этот для одного файла. См. выше.

Цитата Сообщение от retah Посмотреть сообщение
Самое интересное, что если распаковать такой архив винраром, то все отлично.
Это проблема винрара.
Такое поведение самостоятельно закодить тоже возможно.

Добавлено через 6 минут
Цитата Сообщение от retah Посмотреть сообщение
В чем проблема?
В применении не того средства и не тем способом, для которого оно предназначено.
Озвучьте исходную задачу.
0
0 / 0 / 0
Регистрация: 12.09.2017
Сообщений: 36
28.06.2018, 10:45  [ТС] 3
Rius, задача такая, нужно заархивировать файл. Поскольку он большой, то я беру массив байтов из большого файла, архивирую этот массив байтов и так пока файл не закончится. На выходе я получаю заархивированные части.

Но мне нужно получить на выходе не части, а единый архив
0
Эксперт .NET
10566 / 6490 / 1506
Регистрация: 25.05.2015
Сообщений: 19,659
Записей в блоге: 14
28.06.2018, 10:49 4
retah,
Какова причина разбития на отдельные части? Видимо, как раз нехватка памяти?
Вы пробовали архивировать исходный файл как поток, не читая его весь в ОЗУ?
0
0 / 0 / 0
Регистрация: 12.09.2017
Сообщений: 36
28.06.2018, 10:53  [ТС] 5
Rius, естественно, если файл весит больше гб чем объем озу, то делю его на части.

Добавлено через 2 минуты
Rius, как поток? Не совсем понимаю
0
Эксперт .NET
10566 / 6490 / 1506
Регистрация: 25.05.2015
Сообщений: 19,659
Записей в блоге: 14
28.06.2018, 10:56 6
Раз так...
Не надо его весь читать в ОЗУ.
Архивируйте на лету. Тогда до его размера вообще дела не никакого не будет.

Добавлено через 1 минуту
Цитата Сообщение от retah Посмотреть сообщение
как поток? Не совсем понимаю
См. public static void Compress в справке по GZipStream.
Можно юзать готовый метод CopyTo.
Можно реализовать его самостоятельно, что даёт возможно прикрутить отображение прогресса выполнения операции.
0
0 / 0 / 0
Регистрация: 12.09.2017
Сообщений: 36
28.06.2018, 10:56  [ТС] 7
Rius, можно пример, как архивировать не записывая массив байтов в память
0
Эксперт .NET
10566 / 6490 / 1506
Регистрация: 25.05.2015
Сообщений: 19,659
Записей в блоге: 14
28.06.2018, 11:00 8
Лучший ответ Сообщение было отмечено Usaga как решение

Решение

Смысл в том, что в ОЗУ создаётся буфер относительно небольшого размера. В него читается часть исходного файла. Затем он скидывается в поток GZipStream, где уже сжимается. Потом снова читается новая часть... И так до завершения.

Добавлено через 58 секунд
Цитата Сообщение от retah Посмотреть сообщение
можно пример, как архивировать не записывая массив байтов в память
Один по ссылке выше.
Другой в GZipStream. Сжатие, распаковка файла. Только
C#
1
Byte[] buffer = new Byte[fsInput.Length];
заменить на
C#
1
Byte[] buffer = new Byte[1024 * 1024];
Добавлено через 2 минуты
Там ниже, кстати, поправили этот момент: GZipStream. Сжатие, распаковка файла.
0
0 / 0 / 0
Регистрация: 12.09.2017
Сообщений: 36
28.06.2018, 11:10  [ТС] 9
Rius, тогда получается нужно будет создавать дополнительные файлы, чтобы затем их читать?
0
Эксперт .NET
12079 / 8388 / 1281
Регистрация: 21.01.2016
Сообщений: 31,601
28.06.2018, 11:27 10
Цитата Сообщение от retah Посмотреть сообщение
тогда получается нужно будет создавать дополнительные файлы, чтобы затем их читать?
Нет.
0
Эксперт .NET
10566 / 6490 / 1506
Регистрация: 25.05.2015
Сообщений: 19,659
Записей в блоге: 14
28.06.2018, 11:31 11
Цитата Сообщение от retah Посмотреть сообщение
тогда получается нужно будет создавать дополнительные файлы, чтобы затем их читать?
Пример по последней ссылке изучите внимательно.
0
28.06.2018, 11:31
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.06.2018, 11:31
Помогаю со студенческими работами здесь

Найти произведение целых частей и сумму дробных частей и вывести их на экран
Задача: Выделить целую и дробную части заданных N вещественных чисел и найти произведение целых...

Разбиение web-приложения на множество частей и сбор этих частей на стороне клиента в Веб-браузере
Здравствуйте! Есть стороннее WEB-приложение, с помощью которого на сервер можно отправлять...

На сколько частей и как нужно разделить отрезок, чтобы произведение длин частей было максимальным
Помогите написать вот такую программу. Не могу ничего придумать. Может методом перебора или еще...

Скрипт создания 7z архива: добавить дату к названию архива
Добрый день! Заранее извиняюсь если пишу не в той ветке форума. Есть скрипт: &quot;c:\program...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru