7

Скажем, у вас есть файл, который вы хотите поместить в архив .zip:

zip a1.zip foo.dll

Мой тестовый DLL-файл составляет ~ 10 МБ, а архив оказывается 3,5 МБ.

Затем вы создаете файл с точно таким же содержимым и помещаете их в архив:

cp foo.dll bar.dll
zip a2.zip foo.dll bar.dll

Вы можете ожидать, что ZIP достаточно умен, чтобы понять, что это повторяющиеся данные и использовать только один объект сжатия внутри .zip, но это не так: a2.zip имеет размер 7.0 МБ!

В основном большинство таких утилит ведут себя аналогично (tar.gz, tar.bz2, rar в твердом режиме) - только 7zip поймал меня, и результирующий a2.7z лишь незначительно больше, чем a1.7z.

Таким образом, вопрос заключается в следующем: возможно ли создать файл .zip, чтобы избежать потери пространства? Мы создаем файлы .zip с кодом C++, который использует проект minizip из zlib.


Почему нам это надо?

Мы поставляем наше программное обеспечение в форме «.exe installer» и «.zip file». Программное обеспечение на самом деле не требует установки, вы можете просто распаковать его и использовать. Опцию .zip предпочитают крупные клиенты, которые имеют много рабочих станций и используют службы автоматического развертывания / обновления программного обеспечения.

Недавно мы представили три файла .dll, которые теперь нужно поместить в две разные папки, чтобы они использовались разными компонентами (по техническим причинам только один центральный каталог для этих файлов невозможен). Эти три .dll-файла являются точными копиями в обеих папках. Установщик .exe выясняет это, поскольку мы инструктируем его использовать один и тот же сжатый большой двоичный объект для каждого из двух назначений. Но в случае с .zip дело обстоит иначе, и полученная в результате установка становится на 15 МБ больше, что означает более широкое использование полосы пропускания, более медленное время загрузки и вызывающий раздражение тип недовольных инженеров. Кроме того, установка .zip неожиданно становится больше, чем установка .exe, поэтому нас спросят, что мы пропустили при установке .exe.

Есть несколько потенциальных решений для этого,

  • Используйте 7-zip: босс, однако, категорически против этого, так как это заставляет вышеупомянутых людей с автоматическим развертыванием изменять свои сценарии для соответствия 7-zip.
  • Используйте символические ссылки: если вы поместите символическую ссылку внутри .zip, которая указывает на другой файл внутри .zip, она будет сохранена как ссылка (например, с помощью параметра --symlinks для zip). Надеемся, что unarchivers под Win32 будет достаточно любезен, чтобы поддержать их и извлечь копию файла по пути, где должна быть расположена символическая ссылка. Fe WinRAR делает это, но есть много программ, которые «могут делать .zip», и я не уверен, что все так делают.

3 ответа3

1

Вы можете поместить два файла в несжатый zip-файл (например, с 7-Zip), а затем снова поместить полученный файл в zip-файл.

0

Вы можете решить свою проблему, написав небольшой модуль для архивирования. Вы можете распространять этот архиватор среди пользователей, чтобы они использовали его для распаковки zip, или, что еще лучше, внедрить модуль как часть вашего.Сама программа EXE. Модуль может быть C # консольной программой с чем-то вроде этого:

        private static void Extract(string filename)
        {
            //ZipInputStream zi = new ZipInputStream (File.Open ("", FileMode.Open));
            using (ZipInputStream s = new ZipInputStream(File.OpenRead(filename))) {

                ZipEntry theEntry=null;
                while ((theEntry = s.GetNextEntry()) != null) 
                {

                    Console.WriteLine(theEntry.Name);

                    string directoryName = Path.GetDirectoryName(basedir + "ext" + Path.DirectorySeparatorChar + theEntry.Name);
                    string fileName = Path.GetFileName(basedir + "ext" + Path.DirectorySeparatorChar  + theEntry.Name);
                    Console.WriteLine("And the path is:" + basedir +  "ext" + Path.DirectorySeparatorChar  + theEntry.Name);

// create directory
                    if ( directoryName.Length > 0 ) {
                        //Console.WriteLine("DIRECTORY IS SOMETHING");
                        Directory.CreateDirectory(directoryName);
                    }

                    if (fileName != String.Empty) {
                        using (FileStream streamWriter = File.Create(basedir+"DLL_PATH" + Path.DirectorySeparatorChar  + theEntry.Name)) {

                            int size = 2048;
                            byte[] data = new byte[2048];
                            while (true) {
                                size = s.Read(data, 0, data.Length);
                                if (size > 0) {
                                    streamWriter.Write(data, 0, size);
                                } else {
                                    break;
                                }
                            }
                        }
                    }
                }
                  System.IO.File.Copy("source.dll", "destination.dll"); //IMPORTANT

            }

        }

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

System.IO.File.Copy("source.dll", "destination.dll"); //IMPORTANT

Убедитесь, что вы включили в него DLL-файл SharpZipLib с открытым исходным кодом, и это использованные пространства имен:

using System;
using ICSharpCode.SharpZipLib;
using ICSharpCode.SharpZipLib.Zip;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
0

Я предлагаю две альтернативы:

  • распространять самораспаковывающийся .exe (не установщик), который создает каталог, в котором все файлы находятся в правильном относительном месте (тогда клиенту просто нужно перетащить каталог в нужное ему место). Если вы используете 7zip для создания того, что у вас было бы преимущество меньшего пространства, более того, он может быть открыт как архив самим 7zip, если люди его установили.
  • примите простоту и оставайтесь с простым .zip с дублированными файлами. Является ли пропускная способность такой большой проблемой? Разве пользователи не будут жаловаться на вещи, которые не работают должным образом / не в состоянии выполнить сложную процедуру установки? С точки зрения клиента, это, вероятно, не проблема: 16 МБ обычно занимают не более 1 минуты, и не приходится загружать один и тот же файл каждый день. Конечно, это зависит от размера всего установщика: если разница между 5 МБ и 21 МБ, я бы тоже беспокоился об этом.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .