You are not logged in.
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
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
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
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
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
how can unzip password protected zip?
Offline
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
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
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
Ok, got it ![]()
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
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