Místa není nikdy dost a proto může být vhodné aby náš program napsaný v Delphi umožňoval kompresovat uživatelská data.
Základem je se rozhodnout jakým způsobem budeme data pakovat, zda použijeme některý ze standardních formátů (ZIP, RAR, 7z) nebo budeme jen balit proud (stream) dat s případnou naší hlavičkou, v horším případě se pokusíme o vytvoření vlastního formátu (proč?).
Dle mé zkušenosti je výhodné použít kompresi streamu dat např. při ukládání větších dat do databáze a např. ZIP formát (případně s heslem) pro práci s více soubory.
Komprese streamu dat
Delphi od nepaměti obsahuje už v základní instalaci podporu pro práci s kompresními a dekompresními streamy díky Zlib (Jean-loup Gailly a Mark Adler) a to ve verzi 1.2.3 - viz. "Embarcadero\RAD Studio\7.0\source\Win32\rtl\common\ZLib.pas". Výsledkem je celkem kvalitní komprese, která na rozdíl od implementace od MS v .NET nevykazuje problémy s hůře komprimovatelnými soubory (pro .NET hledejte ManagedZLib.dll nebo ZLib.NET).
Pro použití přidejte do uses zlib a pak již můžete používat např. TDecompressionStream nebo TCompressionStream a jejich použití je celkem jasné. Základní je třeba něco takového
oDeflate := TDecompressionStream.Create(zdrojový stream, třeba soubor);
try
oFileStream.CopyFrom(oDeflate, originální velikost souboru);
finally
oDeflate.Free;
end;
nebo
with TCompressionStream.Create(clMax, cílový stream) do
begin
try
CopyFrom(zdroj nepř. oFileStream, oFileStream.Size);
finally
Free;
end;
end;
Komprese souborů
Jsem zastáncem standardních kompresních formátů, takže se jich přidržím. Můžete začít např. příslušnou sekcí na torry.net, nebo zkusit slavnou TurboPower Abbrevia, uvolněnou jako Open Source, což je knihovna podporující PKZIP 4 (tj. ZIP), Microsoft CAB, TAR a gzip, a navíc samorozbalující archívy s podporou Delphi 6 - 2010 (aktuální verze je 3.05, Licence: MPL1.1).
Osobně jsem použití komponenty Abbrevia zvažoval, ale nakonec jsem se rozhodl pro knihovnu od 7z. Sice proti Abbrevii mám navíc DLL, ale zato větší podporu formátů, včetně 7z, 64bit ZIPu, větší rychlosti a velmi přehledného rozhraní.
Např. tento kompresní prográmek bežící v konzole.
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils,
sevenzip;
var
iTotal: int64;
// jednoduchý výpis stavu, #8 je BACKSPACE, tj. neustále přepisuji sám sebe
function ProgressCallback(sender: Pointer; total: boolean; value: int64): HRESULT; stdcall;
begin
if not total then
write(Format('%6.2f%%'#8#8#8#8#8#8#8, [100*value / iTotal]))
else
iTotal := value;
Result := S_OK;
end;
procedure testcreate;
var
Arch: I7zOutArchive; // jedná se o interface, takže ho nemusíme uvolnit
begin
// typ archívu je ZIP
Arch := CreateOutArchive(CLSID_CFormatZip);
// přidáme soubor
Arch.AddFile('c:\test.bin', 'folder\test.bin');
// přidáme rekurzivně soubory
Arch.AddFiles('c:\devkitpro\devkitPPC', 'folder', '*.*', true);
// úroveň komprese
SetCompressionLevel(Arch, 5);
// kompresní metoda
SetCompressionMethod(Arch, mzDeflate);
// a zobrazování stavu
Arch.SetProgressCallback(nil, ProgressCallback);
Arch.SetPassword('heslo'); //heslo
// a proveď vytvoření a uložení
Arch.SaveToFile('c:\test.zip');
end;
begin
try
testcreate;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Web: Delphi 7zip plugin API
Licence: MPL1.1
Jo a pokud máte tip na nějakou dobrou ZIP komponentu, tak neváhejte a vložte odkaz do komentářů.