
A mellékelt példa használata előtt – amennyiben a számítógépen még nem elérhető – telepítenünk kell a Microsoft J# futtatórendszert. Ennek módjáról a Bevezetés című szakaszban olvashat.
Bevezetés
A cikkünkben használt módszer a ZIP tömörítésre épül, melynek szabványa hozzáférhető, így az alkalmazások tetszőlegesen beépíthetik a .zip állományok manipulálásának lehetőségét.
Amennyibe C#-ban szeretnénk használni a ZIP tömörítés előnyeit, gondoskodnunk kell arról, hogy – mivel a .NET Framework nem kínál osztályokat a tömörítéshez – a Microsoft J# futtatórendszerre van szükségünk, melyben már elérhetők olyan névterek és osztályok, melyekkel tetszőleges módon tömöríthetjük állományainkat.
A cikk írásakor a J# futtatórendszer a következő címen volt elérhető: http://msdn.microsoft.com/vjsharp/downloads/howtoget.asp. A futtatórendszert egy VJSharpRDPSetup.exe nevű állományba csomagolva tölthetjük le, melynek indítása után az automatikusan a Windows mappájában helyezi el a névtereket tartalmazó DLL-eket, assembly-ket. A kicsomagolt DLL-ek alapértelmezett esetben a <winroot>:\\Windows\Microsoft Visual JSharp .NET\Framework\v1.0.4205 mappába kerülnek.
A java.util és a java.util.zip névterek tartalmazzák a csomagoláshoz szükséges osztályokat. A névterek deklarációja a VJSLIB.DLL állományban található, így a projekthez referenciaként a DLL-t kell megadni.
Alkalmazás
A mellékelt alkalmazásban meg kell adnunk egy tetszőleges mappát a szövegmezőben, mely alkönyvtárakat és állományokat is tartalmaz, és a Tömörítés gombbal becsomagolhatjuk azt egy ZIP kiterjesztésű, a mappa nevével megegyező nevű állományba.
A mellékelt projekt tartalmaz egy Pelda nevű alkönyvtárat, mely rendelkezik két mappával és állományokkal, hogy kipróbálhassuk a tömörítést. A csomagolás végén a csomagolt állomány (a Pelda mappa esetén a Pelda.zip) a mappa szülőkönyvtárában lesz megtalálható, jelen esetben a projektünk mappájában.
A Form TabControl első füle alatt a Pelda mappa állományai és mappái jelennek meg a TreeView kontrolban, míg a másik fül alatt a projektünk mappájának összetétele látható. Ezt utóbbiban jelenik meg a Pelda.zip állományt jelképező csomópont abban az esetben, ha ezt a mappát tömörítjük be.
A csomagolást a ZipFiles metódus végzi úgy, hogy a segítségül hívja a ZipClass.cs állományban található ZipClass osztály metódusait. Első lépésként egy tömbbe gyűjtjük a megadott, tömörítendő mappa állományainak és mappáinak elérési útvonalát.
DirectoryInfo di = new DirectoryInfo(path);
files = Directory.GetFiles(di.FullName);
subdirs = Directory.GetDirectories(di.FullName);
string[] all = new string[files.Length + subdirs.Length];
for(int k=0;k<files.Length;k++)
{
all[k] = files[k];
}
for(int k=0;k<subdirs.Length;k++)
{
all[files.Length + k] = subdirs[k];
}
Majd amennyiben a tároló tömb elemszáma nem nulla, meghívjuk a ZipClass osztály statikus ZipFiles metódusát, átadva neki paraméterként a tömörített állomány nevét, valamint a létrehozott tömböt.
if (all.Length != 0)
{
fname = di.FullName + ".zip";
ZipClass.ZipFiles(fname,all);
}
A mappában létrehozunk egy ideiglenes állományt a tömörítéshez, melybe majd elhelyezzük az elemeket (a ZipEntry objektumokat).
public static void ZipFiles(string zipname,string[] files)
{
string tmp = Path.GetTempFileName();
Létrehozunk egy adatfolyam-objektumot a kimenet számára.
ZipOutputStream to = new ZipOutputStream(new java.io.FileOutputStream(tmp));
Meghívjuk a belső Zip metódusunkat a tényleges tömörítés elvégzéséhez, majd az ideiglenes állományt a megadott elérési útvonalra másoljuk.
Zip(zipname,to,files);
to.close();
System.IO.File.Copy(tmp, zipname, true);
System.IO.File.Delete(tmp);
}
A Zip metódus rekurzív módon megvizsgálja, hogy a kapott tömb – mely a mappa elemeit tartalmazza – adott eleme állomány, vagy mappa. Amennyiben állományt talál, akkor létrehoz egy ZipEntry objektumot, majd elhelyezi azt a ZipOutputStream kimeneti adatfolyamban.
z = new ZipEntry(fi.Directory.Name + "\\" + fi.Name);
...
to.putNextEntry(z);
Amennyiben a talált elem mappa, akkor ismételten lefut a Zip metódus, hogy annak albejegyzései is tömörítésre kerüljenek.
A tömörített állományban úgy helyezzük el az elemeket, hogy a tömörítendő elem elérési útvonala mindig a főmappára mutasson. Vagyis a Pelda mappa Pelda.txt elemének a Pelda mappa közvetlenül szülőmappája, míg a többi állománynak csak közvetetten az, így azok teljes elérési útvonalából le kell vágni a Pelda/…/állománynév.kiterjesztés karakterláncot, és ezt kell megadni a csomagoló algoritmusnak, hogy a mappák és állományok helyesen kerüljenek elhelyezésre a mappában.