HyperLink
Bejelentkezés
E-mail: 
Jelszó: 





Skip Navigation Links
 

ZIP, avagy mappák tartalmának tömörítése


Példaprogram letöltése

12425 bájt

A Software Online hasábjain nemrégiben foglalkoztunk az állományok tömörítésének lehetőségeivel, bemutattunk két módszert ennek megvalósítására. A tömörítési eljárások mindegyike küzd azonban azzal a problémával, hogy nem képes a megadott mappa teljes tartalmát – alkönyvtárainak elemeit – egy tömörített állományban elhelyezni. A módszerek alapegységei az állományok, így a mappáink tartalmának tömörítésekor – mely tetszőleges számú almappa is lehet – egy kis trükköt kell alkalmaznunk.

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.
Zip(zipname,to,all);
...
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.

Cikksorozat



Könyv
Ez a cikk megtalálható ebben a könyvben: C# Software Offline 2003 évkönyv 590. oldal

Felhasználási feltételek
A Software Online szoftverfejlesztői magazin mindegyik cikke, minden megjelent képe, és egyéb publikált anyaga szerzői jog védelme alatt áll! Bármilyen formában történő másodlagos terjesztésük, közzétételük vagy felhasználásuk kizárólag a kiadó előzetes írásbeli engedélyével történhet!

Copyright © 1999-2012 Animare Software Kft. Minden jog fenntartva!
| Készült: Animare Stúdió | Adatvédelem | Kapcsolat |