Java savjet 49: Kako izdvojiti Java resurse iz JAR i zip arhiva

Većina programera Java prilično su jasne o prednostima korištenja JAR datoteke za objedinjavanje svih različitih resursa (odnosno .class datoteka, zvukova i slika) koji čine njihovo Java rješenje. (Ako niste upoznati s JAR datotekama, pogledajte odjeljak Resursi u nastavku.) Vrlo često pitanje koje postavljaju ljudi koji tek počinju ugrađivati ​​JAR datoteke u svoju vreću trikova je: "Kako izvući sliku iz JAR? " Odgovorit ćemo na to pitanje i pružiti nastavu kako bi bilo izuzetno jednostavno izvući bilo koji resurs iz JAR-a!

Učitavanje GIF slike

Recimo da imamo JAR datoteku koja sadrži hrpu .gif slikovnih datoteka koje želimo koristiti u našoj aplikaciji. Evo kako bismo mogli pristupiti slikovnoj datoteci iz JAR-a pomoću JarResources:

JarResources jar = novi JarResources ("Images.jar"); Logotip slike = Toolkit.getDefaultToolkit (). CreateImage (jar.getResource ("logo.gif");

Taj isječak koda pokazuje da možemo stvoriti JarResourcesobjekt inicijaliziran u JAR datoteku koja sadrži resurs koji nas zanima - Images.jar. Zatim JarResources'getResource()metodu koristimo za dobivanje sirovih podataka iz datoteke logo.gif za createImage()metodu AWT alata .

Bilješka o imenovanju

JarResource je prilično jednostavan primjer kako koristiti razne sadržaje koje nudi Java 1.1 za manipulaciju JAR-om i zip arhivskim datotekama.

Kratka napomena o imenovanju. Podrška za arhiviranje u Javi zapravo je započela korištenjem popularnog zip arhivskog formata (pogledajte "Java Savjet 21: Upotrijebite arhivske datoteke za ubrzanje učitavanja apleta"). Dakle, izvorno, u implementaciji Java podrške za manipulaciju arhivskim datotekama, sve su klase i sve ostalo stavljeni u paket java.util.zip; ove klase obično počinju s " Zip." Ali negdje u prelasku na Javu 1.1, moći koje treba promijeniti naziv arhive da bi bile više usmjerene na Javu. Stoga ono što danas nazivamo JAR datotekama su zip datoteke.

Kako radi

Važna podatkovna polja za JarResourcesklasu koriste se za praćenje i spremanje sadržaja navedene JAR datoteke:

javna završna klasa JarResources {public boolean debugOn = false; private Hashtable htSizes = novi Hashtable (); private Hashtable htJarContents = novi Hashtable (); private String jarFileName;

Dakle, instanciranje klase postavlja ime JAR datoteke, a zatim poziva init()metodu da obavi sav stvarni posao:

javni JarResources (niz jarFileName) {this.jarFileName = jarFileName; u tome(); }

Sada se init()metoda gotovo samo učitava u cjelokupni sadržaj navedene JAR datoteke u tablicu raspršivanja (kojoj se pristupa putem imena resursa).

Ovo je prilično pozamašna metoda, pa razložimo je malo dalje. Predavanje ZipFilenam daje osnovni pristup informacijama o zaglavlju JAR / zip arhive. To je slično informacijama iz direktorija u datotečnom sustavu. Ovdje nabrajamo sve unose u ZipFilei izrađujemo hashtable htSizes s veličinom svakog resursa u arhivi:

private void init () {try {ZipFile zf = new ZipFile (jarFileName); Nabrajanje e = zf.entries (); while (e.hasMoreElements ()) {ZipEntry ze = (ZipEntry) e.nextElement (); if (debugOn) {System.out.println (dumpZipEntry (ze)); } htSizes.put (ze.getName (), novi Integer ((int) ze.getSize ())); } zf.close ();

Dalje pristupamo arhivi putem ZipInputStreamklase. ZipInputStreamKlasa se sve čarolije kako bi se omogućilo nam da pročitate svaku od pojedinih resursa u arhivi. Očitavamo točan broj bajtova iz arhive koja sadrži svaki resurs i pohranjujemo te podatke u hashtable htJarContents kojem se može pristupiti imenom resursa:

FileInputStream fis = novi FileInputStream (jarFileName); BufferedInputStream bis = novi BufferedInputStream (fis); ZipInputStream zis = novi ZipInputStream (bis); ZipEntry ze = null; while ((ze = zis.getNextEntry ())! = null) {if (ze.isDirectory ()) {continue; } if (debugOn) {System.out.println ("ze.getName () =" + ze.getName () + "," + "getSize () =" + ze.getSize ()); } int veličina = (int) ze.getSize (); // -1 znači nepoznata veličina. if (size == - 1) {size = ((Integer) htSizes.get (ze.getName ())). intValue (); } bajt [] b = novi bajt [(int) veličina]; int rb = 0; int komad = 0; while ((((int) size - rb)> 0) {chunk = zis.read (b, rb, (int) size - rb); if (komad == - 1) {break; } rb + = komad; } // dodajte internom resursu hashtable htJarContents.put (ze.getName (), b); if (debugOn) {System.out.println (ze.getName () + "rb =" + rb + ", size =" + size + ", csize =" + ze.getCompressedSize ()); }}} catch (NullPointerException e) {System.out.println ("gotovo."); } catch (FileNotFoundException e) {e.printStackTrace (); } catch (IOException e) {e.printStackTrace (); }}

Imajte na umu da je naziv koji se koristi za identifikaciju svakog resursa naziv kvalificirane staze resursa u arhivi, a ne , na primjer, naziv klase u paketu - to jest, ZipEntryklasa iz paketa java.util.zip bi biti imenovan "java / util / zip / ZipEntry", a ne "java.util.zip.ZipEntry."

Posljednji važan dio koda je jednostavni testni pokretački program. Testni upravljački program jednostavna je aplikacija koja uzima naziv JAR / zip arhive i naziv resursa. Pokušava pronaći resurs u arhivi i prijavljuje njegov uspjeh ili neuspjeh:

javna statička void glavna (String [] args) baca IOException {if (args.length! = 2) {System.err.println ("upotreba: java JarResources"); System.exit (1); } JarResources jr = novi JarResources (args [0]); bajt [] buff = jr.getResource (args [1]); if (buff == null) {System.out.println ("Nije moguće pronaći" + args [1] + "."); } else {System.out.println ("Pronađeno" + args [1] + "(length =" + buff.length + ")."); }}} // Kraj klase JarResources.

Eto ti ga. Klasa jednostavna za upotrebu koja skriva svu neurednost korištenu resursa skrivenih u JAR datotekama.

Vježbe za čitatelja

Sad kad imate osjećaj za izdvajanje resursa iz arhivske datoteke, evo nekoliko uputa koje biste možda željeli istražiti u modificiranju i proširivanju JarResourcesklase:

  • Umjesto da sve učitate tijekom gradnje, napravite odgođeno utovar. U slučaju velike JAR datoteke, možda neće biti dovoljno memorije za učitavanje svih datoteka tijekom izrade.
  • Umjesto da jednostavno pružimo generičku metodu pristupa poput getResource(), mogli bismo pružiti druge pristupnike specifične za resurse - na primjer, getImage()koji vraća Java Imageobjekt getClass(), koji vraća Java Classobjekt (uz pomoć prilagođenog učitavača klasa), i tako dalje. Ako je JAR datoteka dovoljno mala, mogli bismo unaprijed izgraditi sve resurse na temelju njihovih ekstenzija (.gif, .class i tako dalje).
  • Neke bi metode trebale pružiti informacije o samoj datoj JAR datoteci (u osnovi omot ZipFile), uključujući: broj Jar / zip unosa; popisivač koji vraća sva imena resursa; pristupnici koji vraćaju duljinu (i druge atribute) određenog unosa; i dodatak koji omogućuje indeksiranje, da navedemo samo neke.
  • JarResourcesmože se proširiti tako da ga koriste apleti. Korištenjem parametara apleta i URLConnectionklase, JAR sadržaj može se preuzeti s mreže umjesto da se arhive otvaraju kao lokalne datoteke. Nadalje, ovu klasu možemo proširiti kao prilagođeni rukovatelj Java sadržajem.

Zaključak

Ako ste željni znati kako izvući sliku iz JAR datoteke, sada imate način. Ne samo da možete obrađivati ​​slike s JAR datotekom, već s novom klasom navedenom u ovom savjetu, izvlačite magiju na bilo kojem resursu iz JAR-a.

Arthur Choi trenutno radi za IBM kao savjetnički programer. Radio je za nekoliko tvrtki, uključujući SamSung Network Laboratory i MITER. Različiti projekti na kojima je radio su sustavi klijent / poslužitelj, raspodijeljeno računanje objekata i upravljanje mrežom. Koristio je brojne jezike u raznim okruženjima operativnog sustava. Programiranjem je počeo 1981. s FORTRAN IV i COBOL. Kasnije je prešao na C i C ++, a s Javom radi oko dvije godine. Najviše ga zanimaju aplikacije Java u područjima spremišta podataka putem širokopojasnih mreža te paralelna i distribuirana obrada putem Interneta (pomoću programiranja zasnovanog na agentima). John Mitchell, zaposlenik, savjetnik i direktor vlastite tvrtke, posljednjih je deset godina uložio u razvoj vrhunskog računalnog softvera,te u savjetovanju i osposobljavanju ostalih programera. Pružio je savjetovanje o Java tehnologiji, kompajlerima, tumačima, web-aplikacijama i internetskoj trgovini. John je u suautorstvu Making Sense of Java: Vodič za menadžere i ostale nas i objavio je članke u programskim časopisima. Pored pisanja stupca Java Tips za JavaWorld, moderira comp.lang.tcl.announce i comp.binaries.geos news grupe.

Saznajte više o ovoj temi

  • Evo datoteke klase JarResources.java//www.javaworld.com/javatips/javatip49/JarResources.java
  • JAR-ovi //www.javasoft.com/products/jdk/1.1/docs/guide/jar/index.html
  • Za više informacija o podršci za arhiviranje na Javi, pogledajte "Java Savjet 21Koristite arhivske datoteke za ubrzanje učitavanja apleta" //www.javaworld.com/javatips/jw-javatip21.html

Ovu je priču "Java savjet 49: Kako izvući Java resurse iz JAR i zip arhiva" izvorno objavio JavaWorld.