#1 2010-07-11 18:33:55

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 5,932
Website

How to unzip or zip files content

First of all, all the zip compression is embedded in an unique Delphi unit, named SynZip.pas, which is meant to replace the default zlib unit of Delphi, and enhance it. It works from
Delphi 7 to Delphi 2010, from the same source code, which is released under a GPL/LGPL/MPL tri-license.

Do you want to compress some data in memory? Use CompressString() and UnCompressString() methods. Both work with RawByteString encoded data:

function test: boolean;
var  tmp: RawByteString;
begin
  tmp := 'some data';
  result := (UnCompressString(CompressString(tmp,False,comp))=tmp);
end;

Do you want to create a zip archive file? Use our TZipWrite class.

procedure TestCompression;
var FN: TFileName;
begin
  FN := ChangeFileExt(paramstr(0),'.zip');
  with TZipWrite.Create(FN) do
  try
    AddDeflated('one.exe',pointer(Data),length(Data));
    assert(Count=1);
    AddDeflated('ident.txt',M.Memory,M.Position);
    assert(Count=2);
  finally
    Free;
  end;
end;

Do you want to read a zip archive file? Use our TZipRead class.

procedure TestUnCompression;
var FN: TFileName;
i: integer;
begin
  FN := ChangeFileExt(paramstr(0),'.zip');
  with TZipRead.Create(FN) do
  try
    i := NameToIndex('ONE.exe');
    assert(i>=0);
    assert(UnZip(i)=Data);
    i := NameToIndex('ident.TXT');
    assert(i>=0);
    assert(Entry[i].info^.zcrc32=crc32(0,M.Memory,M.Position));
  finally
    Free;
  end;
  DeleteFile(FN);
end;

And if you want the file to be embedded to your executable, there is a dedicated Create constructor in the TZipRead just for handling that:
- create your exe file with a TZipRead instance created with it;
- append your zip content to your exe (by using TZipWrite or by using copy /b on command line);
- that's all!

Couldn't it be easier?

Code above was extracted and adapted from our SynSelfTests test unit.

The SynZip.pas unit itself can be downloaded from our Source Code repository, on with most of our projects.

Offline

#2 2010-07-17 10:00:42

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 5,932
Website

Re: How to unzip or zip files content

Question: How to embeded images to EXE file?

We provided some free and open source classes to read a .zip archive bundled (or not) to an exe. You can therefore append any .zip archive to your exe, then extract any picture inside this .zip with one class.

Use the following method:

constructor TZipRead.Create(const aFileName: TFileName; ZipStartOffset, Size: cardinal);

and provide paramstr(0) - i.e. your exe - as aFileName and ZipStartOffset as a minimal original exe size: it will search for the beginning of the .zip file from this offset. Leave Size parameter as 0: it will get the size from the file size itself.

The same class can get any .zip archive embedded as a resource to your exe, if you prefer.

They are two ways of appending .zip content to an exe:

1. use copy /b original.exe+pictures.zip newembedded.exe
2. use the TZipWrite class provided, and its AddFromZip() method to create your exe from Delphi code: you can even compress and append your images on the fly, with no temporary pictures.zip file.

Offline

#3 2010-07-20 07:11:32

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 5,932
Website

Re: How to unzip or zip files content

If you don't need fastest performance available, but very small code size or just prefer one pascal unit, we've release a self-contained 100% pure pascal source code for the same purpose: see our PasZip unit. It contains the same TZipRead and TZipWrite classes. I use this one to create embedded setup files, together with our LVCL units.

The PasZip unit can be accessible in our Source Code repository: login as anonymous, then select Files and get the PasZip unit.

This PasZip unit is expected to work with Delphi up to 2007 version. New Unicode versions (2009/2010) of Delphi are not supported directly: use our SynPas unit instead, of make the corrections.

Offline

#4 2010-07-31 07:23:18

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 5,932
Website

Re: How to unzip or zip files content

I've used such a method, embedding all necessary files as a .zip archive inside the exe resources, then extracting on request.

For example, we use HunSpell.dll external library to implement the spell checking of our SynProject open source tool.

Here is some extract from ProjectSpellCheck.pas:

constructor THunSpell.Create(DictionaryName: string='');
var Temp, HunSpell, Aff, Dic: TFileName;
    i: integer;
begin
  if DictionaryName='' then
    DictionaryName := 'en_US';
  Temp := GetSynopseCommonAppDataPath;
  HunSpell := Temp+'hunspell.dll';
  with TZipRead.Create(HInstance,'Zip','ZIP') do
  try
    Aff := DictionaryName+'.aff';
    if not FileExists(Temp+Aff) then
      StringToFile(Temp+Aff,UnZip(NameToIndex(Aff)));
    Dic := DictionaryName+'.dic';
    if not FileExists(Temp+Dic) then
      StringToFile(Temp+Dic,UnZip(NameToIndex(Dic)));
    if not FileExists(HunSpell) then
      StringToFile(HunSpell,UnZip(NameToIndex('hunspell.dll')));
  finally
    Free;
  end;
  fHunLib := SafeLoadLibrary(HunSpell);
  if fHunLib=0 then
    exit;
  if not LoadEntryPoints then begin
    FreeLibrary(fHunLib);
    fHunLib := 0;
    exit;
  end;
  fDictionaryName := DictionaryName;
  fHunHandle := Hunspell_create(pointer(Temp+Aff),pointer(Temp+Dic));
  if fHunHandle=nil then
    exit;
   (....)
end;

We extract both hunspell.dll and all dictionary files from an embedded .zip resource. It use our free SynZip unit.
See http://synopse.info/fossil/artifact/4ca … a7726e27f9

Here is the content of the ProjectRes.rc file used to create the resource:

Default TXT "Default.ini"
Zip ZIP "ProjectRes.zip"
wizard2 10 "wizard2.png"

All necessary files are stored in the ProjectRes.Zip archive, then extracted on the fly.

Offline

#5 2011-05-17 15:31:44

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 5,932
Website

Re: How to unzip or zip files content

TZipRead and TZipWrite now handle Unicode file name inside zip (UTF-8 encoded).
Follows appendix D as specified by http://www.pkware.com/documents/casestudies/APPNOTE.TXT
Under Unicode Delphi (Delphi 2009/2010/XE), it will allow full Unicode encoding of file name inside the .zip.

It will also allow TZipWrite to append some content to an existing .zip file, with no copy on disk: it will be very fast e.g. for .log adding into a .zip archive.

For both units SynZip and SynZipFiles
See http://synopse.info/fossil/fdiff?v1=42b … 89b5a55f86
and http://synopse.info/fossil/fdiff?v1=48b … b22b2ca8c1

Offline

#6 2012-01-17 09:48:46

proto
Member
From: Russia, Kostroma
Registered: 2011-09-12
Posts: 25

Re: How to unzip or zip files content

how can unzip password protected zip?

Offline

#7 2012-01-17 11:03:31

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 5,932
Website

Re: How to unzip or zip files content

proto wrote:

how can unzip password protected zip?

This feature is not implemented yet.
You can use your own encryption using the SynCrypto unit, if you wish, but it won't be the standard Zip encryption.
For standard Zip encryption (AES or RC4), you'll have to use another unit.

Offline

#8 2012-06-14 06:11:49

PresleyDias
New member
Registered: 2012-06-14
Posts: 6

Re: How to unzip or zip files content

what is `data` in the following code?

procedure TestCompression;
var FN: TFileName;
begin
  FN := ChangeFileExt(paramstr(0),'.zip');
  with TZipWrite.Create(FN) do
  try
    AddDeflated('one.exe',pointer(Data),length(Data));  //here what is data?
    assert(Count=1);
    AddDeflated('ident.txt',M.Memory,M.Position);         //here what is M?
    assert(Count=2);
  finally
    Free;
  end;
end;


im trying this code for compressing a jpg file

procedure TestCompression;
var FN: TFileName;
Data : string;
begin
  FN := ChangeFileExt(paramstr(0),'.zip');
  with TZipWrite.Create(FN) do
  try
    AddDeflated('C:\Documents and Settings\All Users\Documents\leakTracker\14_06_12 11_33_50 AM.jpg',pointer(Data),length(Data));
    assert(Count=1);
except
    on E : Exception do
      free ;
  end;
end;

it does not work, it shows the zip size a s 1 KB

can you tell me what is wrong?

Offline

#9 2012-06-14 13:23:54

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 5,932
Website

Re: How to unzip or zip files content

Both data and M are members of the test class.
They contain some data used to be compressed by the test routines.

Just click on variable with Ctrl on keyboard to navigate to the declaration of each variable.

So you are compressing the test data and name it as a .jpg file.

Offline

#10 2012-06-15 05:00:14

PresleyDias
New member
Registered: 2012-06-14
Posts: 6

Re: How to unzip or zip files content

Ok, got it smile

i tried

procedure SynZipZipper(sZipFileName,sJpegFileName : string);
var
  Data     : string;
  sUmlDPath : string;
begin
 if FileExists(sZipFileName)  then DeleteFile(pchar(sZipFileName));
 with TZipWrite.Create(sZipFileName) do
  try
    AddDeflated(sJpegFileName);
    AddDeflated(FullUmldFilePath);  
  free;
except
    on E : Exception do
    begin
     free;
    end;
  end;

end;

Offline

#11 2012-09-25 12:44:03

Philip Bockaert
New member
Registered: 2012-09-25
Posts: 1

Re: How to unzip or zip files content

procedure synZipZipper(const aSourceFilename,aTargetFilename:string);
    begin if (fileExists(aTargetFilename)) then DeleteFile(aTargetFilename);
          with TZipWrite.Create(aTargetFilename) do
               try AddDeflated(aSourceFilename)
               finally free end
          end;

Offline

#12 2014-03-03 11:30:30

noobies
Member
Registered: 2011-09-13
Posts: 61

Re: How to unzip or zip files content

http://rouse.drkb.ru/components.php#fwzip
open source alternative with plenty of opportunities: large files, few need memory, password protect archive and unarchive, ppmd

Offline

#13 2014-03-03 17:23:47

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 5,932
Website

Re: How to unzip or zip files content

@phillip

This is indeed better with a try... finally Free end to protect your TZipWrite instance.
Like any other Delphi class, by the way. smile

As I wrote above - see http://synopse.info/forum/viewtopic.php?pid=163#p163

Offline

#14 2014-08-04 18:11:42

HSposito
New member
Registered: 2014-08-04
Posts: 3

Re: How to unzip or zip files content

Hi!

I zipped a file in Java using a ZipOutputStream object and when I try to unzip it in Delphi using the TZipRead class I get the error: "Error -2 during zip/deflate process."

Any ideas on how to fix it?

Thanks a lot!

Offline

#15 2014-08-04 19:53:19

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 5,932
Website

Re: How to unzip or zip files content

Are you sure you are creating a valid .zip file, and not some raw "deflate" content?
Are you able to open the generated .zip file within the windows explorer (or Winzip/winrar tool)?

Offline

#16 2014-08-04 20:18:27

HSposito
New member
Registered: 2014-08-04
Posts: 3

Re: How to unzip or zip files content

Thanks for your reply.

Yes, I can open the generated file within Windows Explorer and 7-Zip.

Offline

#17 2014-08-04 21:34:46

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 5,932
Website

Re: How to unzip or zip files content

What is the compression method used?

Offline

#18 2014-08-04 22:48:31

HSposito
New member
Registered: 2014-08-04
Posts: 3

Re: How to unzip or zip files content

Deflate.

Offline

#19 2014-08-04 22:51:51

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 5,932
Website

Re: How to unzip or zip files content

Weird.

Can you send me some file?
Webcontact01 at synopse dot info

Offline

#20 2014-08-09 10:08:00

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 5,932
Website

Re: How to unzip or zip files content

The .zip file you sent to me is in an unsupported format.
The local fileInfo block has zcrc32=0 zzipSize=0 zfullZize=0.
This is clearly stated by the http://www.pkware.com/documents/casestudies/APPNOTE.TXT specifications as a possibility, if the bit 3 of the fileInfo "flags" is set.
A "data descriptor" block has to be recognized and read instead of the local fileInfo block.

We have therefore fixed UnZip() when crc and sizes are stored not within the file header but in this separate data descriptor block, after the compressed data.
It will either:
- Use the ending "central directory" information;
- Or search manually the "data descriptor" from the binary local data.
See http://synopse.info/fossil/info/324905c71ac

We have also added a new TZipRead.RetrieveFileInfo() method for this purpose.

Offline

#21 2014-09-19 14:36:22

Himeko
Member
Registered: 2014-08-12
Posts: 20

Re: How to unzip or zip files content

Congrats, once again your code is the fastest of various I tried:

KAzip (very old component/library, had to update it for unicode/modern delphi)
Delphi's
Synopse

Both for listing and extracting your unit was the fastest after a series of benchmarks (listing the contents of 1000 zips, then extracting 1 a few times over).
Synopse was in both cases some ~10-20% faster than the other 2.

How do you extract a file btw? maybe my proc can be improved someway:

   ss: TZipRead;
   aa: RawByteString;

  ss := TZipRead.Create(zip);
  c := ss.NameToIndex(fil);
  SetLength(aa,ss.Entry[c].infoLocal.zfullSize);
  aa := ss.UnZip(c);
  With TFileStream.Create(s,fmCreate) do begin
    Write(aa[1],ss.Entry[c].infoLocal.zfullSize);
    Free;
  end;

Offline

#22 2014-09-19 15:20:19

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 5,932
Website

Re: How to unzip or zip files content

The following methods are able to unzip files directly into a destination folder:

    /// uncompress a file stored inside the .zip archive into a destination directory
    function UnZip(aIndex: integer; const DestDir: TFileName;
      DestDirIsFileName: boolean=false): boolean; overload;
    /// uncompress a file stored inside the .zip archive into a destination directory
    function UnZip(const aName, DestDir: TFileName;
      DestDirIsFileName: boolean=false): boolean; overload;
    /// uncompress all fields stored inside the .zip archive into the supplied
    // destination directory
    // - returns -1 on success, or the index in Entry[] of the failing file
    function UnZipAll(DestDir: TFileName): integer;

Ensure you retrieved the latest version from our source code repository.

Offline

#23 2014-09-19 19:56:37

Himeko
Member
Registered: 2014-08-12
Posts: 20

Re: How to unzip or zip files content

That works great, didn't see the overloads somehow, thanks.

ps: does the board support watching threads? it would be nice to be able to receive email notifications of replies.

Offline

#24 2014-09-19 21:04:56

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 5,932
Website

Re: How to unzip or zip files content

Himeko wrote:

ps: does the board support watching threads? it would be nice to be able to receive email notifications of replies.

Not the current version, yet.
Sorry.

Offline

#25 2014-09-19 23:24:48

Himeko
Member
Registered: 2014-08-12
Posts: 20

Re: How to unzip or zip files content

Maybe you could migrate the board to phpbb

https://github.com/fluxbb/converter

Offline

Board footer

Powered by FluxBB