Ao colocar dois arquivos idênticos em um .zip, eles ocupam 2x espaço, isso pode ser evitado?

7

Digamos que você tenha um arquivo que deseja colocar em um arquivo .zip:

zip a1.zip foo.dll

Meu arquivo .dll de teste tem ~ 10MB e o arquivo é de 3,5MB

Em seguida, você cria um arquivo com exatamente o mesmo conteúdo e coloca esses dois em um arquivo:

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

Você pode esperar que o ZIP seja inteligente o suficiente para descobrir que isso está repetindo dados e usar apenas um objeto de compactação dentro do .zip, mas este não é o caso: a2.zip é 7.0MB!

Basicamente, a maioria desses utilitários se comportam de maneira semelhante (tar.gz, tar.bz2, rar no modo sólido) - somente 7zip me pegou e o a2.7z resultante é apenas marginalmente maior que a1.7z.

Então a questão é: é possível construir um arquivo .zip onde esse desperdício de espaço é evitado ? Criamos os arquivos .zip com o código C ++, que usa o projeto minizip do zlib.

Por que nós precisamos disso?

Nós enviamos nosso software nos formatos ".exe installer" e ".zip file". O software não requer instalação, você pode simplesmente descompactá-lo e usá-lo. A opção .zip é preferida por clientes grandes que têm muitas estações de trabalho e usam serviços automatizados de implantação / atualização de software.

Introduzimos três arquivos .dll recentemente, que agora precisam ser colocados em duas pastas diferentes, para serem usados por diferentes componentes (somente um diretório central para esses arquivos é impossível por motivos técnicos). Esses três arquivos .dll são cópias exatas em ambas as pastas. O instalador do .exe descobre isso, já que instruímos para usar exatamente o mesmo blob compactado para cada um dos dois destinos. Mas esse não é o caso do .zip e a instalação resultante é 15MB maior, o que significa mais uso de largura de banda, tempos de download mais lentos e tipo de raiva searing engineer-infeliz-that-things-are-optimal. Além disso, a instalação do .zip se torna repentinamente maior do que a instalação do .exe, então seríamos perguntados sobre o que foi omitido na instalação do .exe.

Existem algumas soluções possíveis para isso,

  • Use o 7-zip : no entanto, o chefe é contra isso, já que isso força as pessoas de implantação automatizada mencionadas a modificar seus scripts para acomodar 7-zip.
  • Use links simbólicos : se você colocar um symlink dentro de um .zip, que aponta para outro arquivo dentro do .zip, ele é armazenado como referência (por exemplo, usando a opção --symlinks para zip ). Espero que os unarchivers do Win32 tenham a gentileza de suportá-los e extrair uma cópia do arquivo para o caminho em que o link simbólico deve estar localizado. Por exemplo O WinRAR faz isso, mas há muitos programas que "podem fazer .zip" e não tenho certeza se todos fazem isso dessa maneira.
por anrieff 10.06.2014 / 19:05

3 respostas

1

Você pode colocar os dois arquivos em um arquivo zip não compactado (por exemplo, com 7-Zip) e, em seguida, colocar o arquivo resultante em um arquivo zip novamente.

    
por 11.08.2014 / 14:28
0

Você pode resolver seu problema escrevendo um pequeno módulo de não arquivamento. Você pode distribuir esse un-archiver para os usuários, então eles o usam para extrair o zip ou, melhor ainda, implementar o módulo como parte de seu próprio programa .EXE. O módulo poderia ser o programa de console C # com algo parecido com isto:

        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

            }

        }

Isso não é testado, mas tenho certeza que você pode trabalhar com isso. A parte mais importante é onde você copia o arquivo extraído para a nova dll:

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

Certifique-se de incluir a DLL opensource SharpZipLib com isso e estes são os namespaces usados:

using System;
using ICSharpCode.SharpZipLib;
using ICSharpCode.SharpZipLib.Zip;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
    
por 03.07.2014 / 01:45
0

Eu proponho duas alternativas:

  • distribua uma% auto-extração.exe (não um instalador), que cria um diretório no qual todos os arquivos estão no lugar relativo correto (então o cliente só precisa arrastar e soltar o diretório onde deseja). Se você usar o 7zip para criar, você teria a vantagem de ter um espaço menor, além disso, ele pode ser aberto como um arquivo pelo próprio 7zip, se as pessoas tiverem isso instalado.
  • abraça a simplicidade e fica com o .zip simples com arquivos duplicados. A largura de banda é um grande problema? Os usuários que se queixam de que as coisas não estão funcionando como esperado / que não podem realizar um procedimento de instalação complicado podem ser um problema maior? Do ponto de vista do cliente, provavelmente não é um problema: 16 MB geralmente não levam mais que 1 minuto de download, e não é como se tivessem que baixar o mesmo arquivo todos os dias. É claro que depende do tamanho do instalador inteiro: se a diferença é entre 5 MB e 21 MB eu também me preocuparia com isso.
por 06.08.2014 / 16:22