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

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

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

Студворк — интернет-сервис помощи студентам
Например есть две части 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
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
28.06.2018, 10:29
Ответы с готовыми решениями:

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

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

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

10
Эксперт .NET
 Аватар для Rius
13092 / 7651 / 1672
Регистрация: 25.05.2015
Сообщений: 23,299
Записей в блоге: 14
28.06.2018, 10:43
Цитата Сообщение от retah Посмотреть сообщение
buffer.AddRange(File.ReadAllBytes(pathTo CompressFolder + name));
Никуда не годный способ. При большом размере файла вам ОЗУ не хватит.

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

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

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

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

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

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

Добавлено через 1 минуту
Цитата Сообщение от retah Посмотреть сообщение
как поток? Не совсем понимаю
См. public static void Compress в справке по GZipStream.
Можно юзать готовый метод CopyTo.
Можно реализовать его самостоятельно, что даёт возможно прикрутить отображение прогресса выполнения операции.
0
0 / 0 / 0
Регистрация: 12.09.2017
Сообщений: 36
28.06.2018, 10:56  [ТС]
Rius, можно пример, как архивировать не записывая массив байтов в память
0
Эксперт .NET
 Аватар для Rius
13092 / 7651 / 1672
Регистрация: 25.05.2015
Сообщений: 23,299
Записей в блоге: 14
28.06.2018, 11:00
Лучший ответ Сообщение было отмечено 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  [ТС]
Rius, тогда получается нужно будет создавать дополнительные файлы, чтобы затем их читать?
0
Эксперт .NET
 Аватар для Usaga
14136 / 9356 / 1350
Регистрация: 21.01.2016
Сообщений: 35,168
28.06.2018, 11:27
Цитата Сообщение от retah Посмотреть сообщение
тогда получается нужно будет создавать дополнительные файлы, чтобы затем их читать?
Нет.
0
Эксперт .NET
 Аватар для Rius
13092 / 7651 / 1672
Регистрация: 25.05.2015
Сообщений: 23,299
Записей в блоге: 14
28.06.2018, 11:31
Цитата Сообщение от retah Посмотреть сообщение
тогда получается нужно будет создавать дополнительные файлы, чтобы затем их читать?
Пример по последней ссылке изучите внимательно.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
28.06.2018, 11:31
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
Установка Emscripten SDK (emsdk) и CMake на Windows для сборки C и C++ приложений в WebAssembly (Wasm)
8Observer8 30.01.2026
Чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. Система контроля версиями Git. . .
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru