Do que trata o artigo

Este artigo abordada a compressão de arquivos, quando ela é necessária e como fazê-la. Isso será feito usando o componente TZipMaster. Também aborda streams comprimidas e instaladores com arquivos comprimidos auto extraíveis.


Para que serve

Por vezes é necessário armazenar um arquivo ou backup de modo a ocupar o menor espaço possível em disco. Outras vezes precisamos transferir um arquivo grande por e-mail, FTP ou até TCP/IP e precisamos de alguma forma diminuir o tamanho desse arquivo para que a transferência fique mais rápida. Outra serventia seria criar pacotes de patches já pré-configurados e com os arquivos corretos para que o usuário simplesmente instale.


Em que situação o tema é útil

Sempre que for necessário comprimir, armazenar ou transferir um arquivo ele pode ser comprimido. TZipMaster nos permite criar programas de compressão de arquivos profissionais, como os famosos WinZip e PkZip. Pode ser útil para colocar um compressor embutido na sua aplicação e permitir que seu cliente envie logs do sistema sem custo adicional para ele.

Resumo do DevMan

Embora o Delphi tenha uma biblioteca nativa para compressão de arquivos e streams, a Zlib, o uso do TZipMaster é muito mais fácil. Além disso, com o TZipMaster você pode fazer muito facilmente a compressão de pastas inteiras, o que necessitaria de algum trabalho extra usando Zlib. Além disso, você pode fazer programas de backup profissionais. Os arquivos comprimidos com TZipMaster podem ser facilmente abertos com o WinZip, PkZip ou 7zip. Neste artigo será mostrado um pouco sobre compressão de arquivos, compressão de streams e apresentado um programa para backup de bancos de dados Firebird.

Nas situações em que tudo já foi feito para aumentar a velocidade de uma transmissão de arquivos ou diminuir o espaço em disco que um arquivo consome, a solução pode ser a compressão de arquivos.

Existem vários tipos de compressão para vários tipos e formatos de arquivo. Por exemplo, mp3 é um tipo de compressão de áudio. Um arquivo mp3 é um tipo de arquivo de áudio wav que além de comprimido, são retiradas algumas frequências inaudíveis ao ouvido humano, para que se diminua o tamanho. Analogamente, JPG é um formato de imagem comprimido. Uma foto tirada com uma câmera de 7mpx, se fosse armazenada em bitmap, teria aproximadamente 20mb, enquanto que no formato JPG ela pode ocupar entre 5 e 7mb. Da mesma forma DivX, XviD entre outros são formatos de compressão de vídeo. Embora existam formatos e algoritmos específicos para compressão de certos tipos de dados, existem também algoritmos de compressão de uso geral.

A compressão pode se dar com perdas, onde partes dos dados são perdidos e o arquivo comprimido não pode mais voltar ao estado original. É o que acontece com MP3, DivX e JPG. Mas existem também os algoritmos de compressão sem perda, como o Zip, Rar e Arj.

Nota: Há diversas bibliotecas ou algoritmos de compressão. Exemplos comuns são ACE, RAR, ZIP, 7Z, TAR, ARJ. A maioria desses formatos possui uma API / SDK que também pode ser usada pelo Delphi. O Componente ZipMaster vem junto com uma DLL chamada DelZip190.dll que deve estar em um diretório facilmente encontrado pelo seu programa, seja no mesmo diretório do programa, seja na pasta system32 ou em outro diretório especificado pelo componente.

Neste artigo aprenderemos uma maneira prática de criar arquivos .zip para envio ou transmissão imediata sem exigir que o cliente tenha ou saiba usar um compactador de arquivos. Para isso usaremos o componente TZipMaster. Seu download pode ser feito no site oficial, que pode ser encontrado na seção de links.

Nota: Se ao término da instalação não for possível encontrar uma aba chamada Delphi Zip na Tool Palette o instalador descomprimiu o source, compilou, mas não fez a instalação do componente. Dessa forma é necessário realizar a instalação manual. Isso pode ser feito abrindo a pasta de instalação e carregando o pacote ZMstr190D13.dpk, que é a versão para o Delphi XE e instalá-lo. É necessário também incluir no Libary Path e Search Path o caminho das units do componente.

Streams

Este artigo aborda o uso de Streams. TStream é a classe base para tipos de objetos que podem ler ou salvar em vários tipos de armazenamento como arquivos, memória e outros mais. Mas o que é um TStream. Uma tradução bem aceita é que um TStream é algo como um fluxo de dados, informações. Sendo assim, esse fluxo possui um início e fim, e ao manipular essas informações sempre estaremos em algum desses pontos. Um TStream pode conter qualquer tipo de informação.

Além de ser uma classe base é também abstrata, por isso existem versões especializadas para cada tipo particular de armazenamento. Cada descendente de TStream implementa métodos que permitem transferir dados de forma adequada à sua finalidade. Por exemplo, se você utilizar um descendente de TStream destinado à utilização de arquivos, seus métodos são codificados para tratar somente esse tipo e de forma eficiente. O TStream também disponibiliza para as aplicações meios de localizar uma posição específica no conjunto de dados que ele contém e ainda fornece informações sobre esses dados, como seu tamanho e posição corrente durante a leitura.

A classe TStream é muito versátil, permite seu trabalho em conjunto com componentes para facilitar o uso nos mais diversos tipos de formulários. Como já mencionado, a classe TStream é abstrata e não deve ser instanciada, seus métodos são puramente virtuais que são sobrecarregados em classes descendentes. Aqui temos algumas dessas classes:

TFileStream – Deve ser utilizado para acessar informações contidas em arquivos. Um objeto do tipo TFileStream abre um arquivo e disponibiliza métodos para leitura e gravação;

TStringStream – Permite que informações sejam armazenadas no formato string, porém com recursos de I/O. Seu uso comum é de atuar como um objeto intermediário entre algum processo, contendo texto que será utilizado posteriormente;

TMemoryStream – Armazena informações em um buffer dinâmico de memória. Por estar em memória seu processamento é veloz, além de que também oferece mecanismos para manipulação das informações contidas. Assim como o TStringStream, é muito utilizado também como uma forma de objeto temporário, entre um processo e outro;

TBlobStream – Este atua diretamente sobre os campos BLOB de um DataSet do BDE. Também trabalha com os campos TMemoField e TGraphicField para leitura e escrita de dados;

TWinSocketStream – Disponibiliza meios para que aplicações troquem informações através de conexões socket;

TOleStream – Permite a leitura e escrita de informação disponibilizada através de um objeto OLE

Como um TStream pode armazenar qualquer tipo de informações, isso significa que até mesmo objetos da VCL podem ser contidos dentro dele. Um uso clássico para TStream é a possibilidade de se armazenar em um meio físico o estado de um dado objeto, isso é uma forma de persistência de objetos. Por exemplo, imagine um TListBox onde os usuários adicionam informações em tempo de execução. Depois essas informações precisam ser salvas em algum lugar para que sejam recuperadas em um uso subsequente. Para muitos a solução seria ter uma tabela em um banco de dados ou criar até mesmo um arquivo texto e lançar ali o conteúdo desse objeto. Não são ideias ruins, mas elas custam um pouco mais de código. Uma solução alternativa é fazer uso do TStream.

O próprio Delphi utiliza esse tipo de persistência. Toda vez que um projeto é salvo ele grava em disco o conteúdo de seus objetos, assim quando o projeto é recarregado o Delphi coloca tudo de volta como estava. No código a seguir é possível ver como um objeto TListBox pode ser salvo na forma de arquivo:


  procedure TForm1.FormClose(
    Sender: TObject; 
    var Action: TCloseAction);
  var
    strm : TFileStream;
  begin
    strm := TFileStream.Create('MinhaLista.DAT', fmCreate);
    strm.WriteComponent(ListBox1);
    strm.Free;
  end; 

Já no código seguinte o valor é recuperado:


  procedure TForm1.FormCreate(
    Sender: TObject);
  var
    strm : TFileStream;
  begin
    if FileExists('MinhaLista.DAT') then 
    begin
      strm := TFileStream.Create('MyList.DAT', fmOpenRead);
      strm.ReadComponent(ListBox1);
      strm.Free;
    end;
  end;  ... 

Quer ler esse conteúdo completo? Tenha acesso completo