
A mellékelt példaprogram megnyitása előtt a CompressStream.pas-ban lévő komponenst telepítenie kell a Delphi alá. Ehhez válassza a Component - Install Component menüpontot.
A Delphi CD-jén elrejtve megtalálhatóak azok a forráskódok, melyek a tömörítő algoritmust megvalósítják, így nekünk már csak ennek a felhasználását kell megismernünk.
Ahhoz, hogy használni tudjuk ezt a lehetőséget bármely programunkban, így ebben a példaprogramban is, először szükség lesz arra, hogy a CD-ről bemásoljuk ezeket az állományokat a megfelelő helyre.
A CD meghajtón a "\INFO\EXTRAS\ZLIB\OBJ" könyvtár teljes tartalmát másoljuk a "C:\Program Files\Borland\Delphix\Lib" könyvtárba. (Az elérési útvonalban az x helyére értelemszerűen az adott Delphi verziószáma kerül.)
Továbbá "\INFO\EXTRAS\ZLIB"-ben található Zlib.pas és Zlib.dcu állományokat szintén másoljuk az előbbi könyvtárba.
Ettől kezdve már hivatkozhatunk Zlib unit-ra forráskódjainkban.
Komponensben két eljárást hozunk létre, Compress illetve Decompress néven melyek elvégzik a tömörítést illetve kibontást.
Első lépésként foglalunk egy memória területet, melyre kiolvassuk a tömörítendő adatfolyam tartalmát.
procedure TCompressStream.Compress(input, output: TStream);
begin
GetMem(pIn, input.Size);
input.Position := 0;
inCount := input.Read(pIn^, input.Size);
Ezt követően a CompressBuf függvény hívásával elvégezzük e memória területnek a tömörítését. Tömörített adatok a harmadik paraméterben megadott memória területre kerülnek. Tömörített adathalmaz méretét a negyedik paraméterben kapjuk vissza.
CompressBuf(pIn, inCount, pOut, outCount);
Ezek ismeretében a létrejött adathalmazt kiírjuk a kimeneti adatfolyamba, majd felszabadítjuk a lefoglalt memória területeket.
output.Write(pOut^, outCount);
FreeMem(pIn);
FreeMem(pOut);
end;
Az adatok kibontását a Decompress eljárásunk végzi el. E műveletnek csak akkor állunk neki, ha az átadott adatfolyam ténylegesen tartalmaz adatokat.
procedure TCompressStream.Decompress(input, output: TStream);
begin
input.Position :=0;
if input.Size> 0 then begin
Hasonlóan az előzőekhez, ismét memória területet foglalunk, melyre kiírjuk a tömörített adatfolyam tartalmát.
GetMem(pIn, input.Size);
input.Read(pIn^, input.Size);
A DecompressBuf függvény meghívásával elvégeztetjük a kibontást. Az eredményt a negyedik paraméterben megadott memória területre kapjuk. A kibontott adathalmaz méretét az ötödik paraméterben kapjuk vissza.
DecompressBuf(pIn, input.Size, 0, pOut, outCount);
A kibontott adatokat kiírjuk a kimeneti adatfolyamba, majd felszabadítjuk a lefoglalt memória területeket.
output.Write(pOut^, outCount);
FreeMem(pIn);
FreeMem(pOut);
end;
output.Position := 0;
end;
Teszt alkalmazás
Az elkészült komponenseket rögtön ki is próbáljuk, oly módon, hogy egy Memo komponensben lévő szöveget tömörítünk, majd kibontunk.
Létrehozunk két memóriabeli adatfolyamot (TMemoryStream), melyeket az adatok átadásához használunk fel. Az első adatfolyamba töltjük a Memo1 komponens szövegét, majd meghívjuk a komponensünk Compress függvényét.
procedure TForm1.Button1Click(Sender: TObject);
begin
ms1:=TMemoryStream.Create;
ms2:=TMemoryStream.Create;
Memo1.Lines.SaveToStream(ms1);
CompressStream1.Compress(ms1, ms2);
A kapott eredményt lementjük egy 1.txt nevű állományba, melyet betöltünk megjelenítés céljából a Memo2 komponensbe.
ms2.SaveToFile(ExtractFilePath(Application.ExeName)+'\1.txt');
Memo2.Lines.LoadFromFile(ExtractFilePath(Application.ExeName)+'\1.txt');
ms1.Free;
ms2.Free;
end;
A második nyomógomb lenyomására végezzük el a kibontást. Ez hasonlóan történik, mint az előbb, létrehozunk két memóriabeli adatfolyamot, az elsőbe betöltjük a tömörített adatokat, majd meghívjuk komponensünk Decompress eljárását.
procedure TForm1.Button2Click(Sender: TObject);
begin
ms1:=TMemoryStream.Create;
ms2:=TMemoryStream.Create;
ms1.LoadFromFile(ExtractFilePath(Application.ExeName)+'\1.txt');
CompressStream1.Decompress(ms1, ms2);
A kapott eredményt lementjük egy 2.txt nevű állományba, melyet megjelenítés céljából betöltünk a Memo3 komponensbe is.
ms2.SaveToFile(ExtractFilePath(Application.ExeName)+'\2.txt');
Memo3.Lines.LoadFromFile(ExtractFilePath(Application.ExeName)+'\2.txt');
ms1.Free;
ms2.Free;
end;