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

Сжатие набора файлов

07.09.2019, 13:10. Показов 1481. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Есть некая структура папок с файлами, в коде имеется список FileInfo файлов, которые нужно заархивировать, при том так, что бы структура папок сохранилась, желательно всё это без создания временных файлов (ибо если запустить два таких алгоритма сразу, что более чем будет происходить, привет многопоточность, то временные файлы будут пересекаться и ломаться), ZipFile может только сразу всю папку корневую заархивировать, а мне нужно что бы были только определенные файлы, GZipStream, судя по статье https://www.codeproject.com/Ar... ress-Files сжимает только файлы, не учитывая папки, т.е. структуру папок в архиве с его помощью не сохранишь, идеи?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.09.2019, 13:10
Ответы с готовыми решениями:

Сжатие текстовых файлов за алгоритмом GZIP
Здравствуйте! У меня возникла следующая проблема - сжать текстовый файл (с расширением txt) за алгоритмом GZIP. Вот нашел материал по...

Сжатие/разжатие бинарных файлов (SharpZipLib)
Требуется распаковать бинарный файл в некий temp-файл, выполнить с ним определённые действия в программе и затем заново запаковать. Имеется...

Потоки (threads) и сжатие файлов
Всем привет! Я недавно изучаю C#, пытаюсь самостоятельно выполнять практические задания. Есть задание, общая суть такая:...

5
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18270 / 14193 / 5368
Регистрация: 17.03.2014
Сообщений: 28,881
Записей в блоге: 1
07.09.2019, 14:44
Nordicus666, можно с помощью ZipArchive путем добавления файлов по одному. Для файлов из папки делаем цикл разумеется.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string zipPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.zip");
using (var stream = File.Create(zipPath))
using (ZipArchive zip = new ZipArchive(stream, ZipArchiveMode.Update))
{
    // Файл в корне архива
    zip.CreateEntryFromFile(
        sourceFileName: Environment.ExpandEnvironmentVariables(@"%windir%\notepad.exe"),
        entryName     : "notepad.exe"
    );
    // Файл в папке внутри архива
    zip.CreateEntryFromFile(
        sourceFileName: Environment.ExpandEnvironmentVariables(@"%windir%\System32\drivers\etc\hosts"),
        entryName     : @"System32\drivers\etc\hosts"
    );
}
0
7 / 7 / 0
Регистрация: 05.04.2016
Сообщений: 410
07.09.2019, 15:20  [ТС]
как вариант, но, опять же, если вызвать два алгоритма сразу, надо пилить разные архивы с разными наборами файлов, это сломает систему, либо, если сделать защиту, будет создавать много временных архивов (они в виде файлов нужны только для отправки), уже нашёл такой вот вариант: https://www.codeproject.com/Ti... irectories
я не додумался просто архивировать так же и путь в виде текста банально, а так же плюс этого метода, что данные сохраняются в stream, т.е. никаких временных файлов делать не нужно, просто потом из этого MemoryStream вытащить байты и отправить по сети, на клиенте разархивировать в memoryStream обратно, а после просто читать путь и байты файла, путь и байты файла и т.п.
копия кода с codeproject.com
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// via https://www.codeproject.com/Tips/319438/How-to-Compress-Decompress-directories
using System;
using System.Text;
using System.IO;
using System.IO.Compression;
 
namespace CmprDir
{
  class Program
  {
    delegate void ProgressDelegate(string sMessage);
 
    static void CompressFile(string sDir, string sRelativePath, GZipStream zipStream)
    {
      //Compress file name
      char[] chars = sRelativePath.ToCharArray();
      zipStream.Write(BitConverter.GetBytes(chars.Length), 0, sizeof(int));
      foreach (char c in chars)
        zipStream.Write(BitConverter.GetBytes(c), 0, sizeof(char));
 
      //Compress file content
      byte[] bytes = File.ReadAllBytes(Path.Combine(sDir, sRelativePath));
      zipStream.Write(BitConverter.GetBytes(bytes.Length), 0, sizeof(int));
      zipStream.Write(bytes, 0, bytes.Length);
    }
 
    static bool DecompressFile(string sDir, GZipStream zipStream, ProgressDelegate progress)
    {
      //Decompress file name
      byte[] bytes = new byte[sizeof(int)];
      int Readed = zipStream.Read(bytes, 0, sizeof(int));
      if (Readed < sizeof(int))
        return false;
 
      int iNameLen = BitConverter.ToInt32(bytes, 0);
      bytes = new byte[sizeof(char)];
      StringBuilder sb = new StringBuilder();
      for (int i = 0; i < iNameLen; i++)
      {
        zipStream.Read(bytes, 0, sizeof(char));
        char c = BitConverter.ToChar(bytes, 0);
        sb.Append(c);
      }
      string sFileName = sb.ToString();
      if (progress != null)
        progress(sFileName);
 
      //Decompress file content
      bytes = new byte[sizeof(int)];
      zipStream.Read(bytes, 0, sizeof(int));
      int iFileLen = BitConverter.ToInt32(bytes, 0);
 
      bytes = new byte[iFileLen];
      zipStream.Read(bytes, 0, bytes.Length);
 
      string sFilePath = Path.Combine(sDir, sFileName);
      string sFinalDir = Path.GetDirectoryName(sFilePath);
      if (!Directory.Exists(sFinalDir))
        Directory.CreateDirectory(sFinalDir);
 
      using (FileStream outFile = new FileStream(sFilePath, FileMode.Create, FileAccess.Write, FileShare.None))
        outFile.Write(bytes, 0, iFileLen);
 
      return true;
    }
 
    static void CompressDirectory(string sInDir, string sOutFile, ProgressDelegate progress)
    {
      string[] sFiles = Directory.GetFiles(sInDir, "*.*", SearchOption.AllDirectories);
      int iDirLen = sInDir[sInDir.Length - 1] == Path.DirectorySeparatorChar ? sInDir.Length : sInDir.Length + 1;
 
      using (FileStream outFile = new FileStream(sOutFile, FileMode.Create, FileAccess.Write, FileShare.None))
      using (GZipStream str = new GZipStream(outFile, CompressionMode.Compress))
        foreach (string sFilePath in sFiles)
        {
          string sRelativePath = sFilePath.Substring(iDirLen);
          if (progress != null)
            progress(sRelativePath);
          CompressFile(sInDir, sRelativePath, str);
        }
    }
 
    static void DecompressToDirectory(string sCompressedFile, string sDir, ProgressDelegate progress)
    {
      using (FileStream inFile = new FileStream(sCompressedFile, FileMode.Open, FileAccess.Read, FileShare.None))
      using (GZipStream zipStream = new GZipStream(inFile, CompressionMode.Decompress, true))
        while (DecompressFile(sDir, zipStream, progress));
    }
 
    public static int Main(string[] argv) 
    {
      if (argv.Length != 2)
      {
        Console.WriteLine("Usage: CmprDir.exe <in_dir compressed_file> | <compressed_file out_dir>");
        return 1;
      }
 
      string sDir;
      string sCompressedFile;
      bool bCompress = false;
      try
      {
        if (Directory.Exists(argv[0]))
        {
          sDir = argv[0];
          sCompressedFile = argv[1];
          bCompress = true;
        }
        else
          if (File.Exists(argv[0]))
          {
            sCompressedFile = argv[0];
            sDir = argv[1];
            bCompress = false;
          }
          else
          {
            Console.Error.WriteLine("Wrong arguments");
            return 1;
          }
 
        if (bCompress)
          CompressDirectory(sDir, sCompressedFile, (fileName) => { Console.WriteLine("Compressing {0}...", fileName); });
        else
          DecompressToDirectory(sCompressedFile, sDir, (fileName) => { Console.WriteLine("Decompressing {0}...", fileName); });
 
        return 0;
      }
      catch (Exception ex)
      {
        Console.Error.WriteLine(ex.Message);
        return 1;
      }
    }
  }
}
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18270 / 14193 / 5368
Регистрация: 17.03.2014
Сообщений: 28,881
Записей в блоге: 1
07.09.2019, 15:31
Nordicus666, в моем примере достаточно заменить FileStream на MemoryStream. И - вуаяля! - архивация в памяти. Единисвенное что в случае с GZipStream будет возможно организовать потоковое сжатие без необходимости держать весь архив в памяти как в случае с ZipArchive.
0
7 / 7 / 0
Регистрация: 05.04.2016
Сообщений: 410
07.09.2019, 15:50  [ТС]
держать в памяти множество раз по 200+Мб (каждый отправляемый файл)(хоть и в сжатом виде меньше будет) не очень как то, если честно)
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18270 / 14193 / 5368
Регистрация: 17.03.2014
Сообщений: 28,881
Записей в блоге: 1
07.09.2019, 15:54
Nordicus666, значит используй решение с GZipStream с codeproject.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.09.2019, 15:54
Помогаю со студенческими работами здесь

Комбинирование потоков данных(сжатие файлов)
Написать простую утилиту для сжатия файлов (т.е. соединить выход одного потока данных со входом другого, чтобы реализовать сложное...

Сжатие и запись файлов с учётом различий в скорости дисков
Пишу многопоточный архиватор gz-шник(а точнее уже написал) с помощью GZipStream. Поток на &quot;чтение&quot; бьёт на блоки сорсный файл и...

Сжатие файлов
Здравствуйте, подскажите как можно сжать файлы в Windows 7 ? (avi, mkv) И так, чтобы их можно было потом записать на диск и смотреть на...

Сжатие файлов
Обьясните нубу почему при сжатии gzip размер файла у меня наоборот увеличивается??? Например при просмотре файла до сжатия командой ls -l...

Сжатие файлов
Здравствуйте) Скажите пожалуйста, как можно сжать zip (rar) архивы и папки? То есть памяти на дисках уже маловато, а все нужное и если бы...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
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