Προγραμματισμός

Συμβουλή Java 49: Πώς να εξαγάγετε πόρους Java από αρχεία JAR και zip

Οι περισσότεροι προγραμματιστές Java είναι αρκετά σαφείς σχετικά με τα πλεονεκτήματα της χρήσης ενός αρχείου JAR για να συγκεντρώσουν όλους τους διάφορους πόρους (δηλαδή αρχεία .class, ήχους και εικόνες) που αποτελούν τη λύση Java. (Εάν δεν είστε εξοικειωμένοι με τα αρχεία JAR, ανατρέξτε στην ενότητα Πόροι παρακάτω.) Μια πολύ συχνή ερώτηση που ρωτήθηκε από άτομα που μόλις αρχίζουν να ενσωματώνουν αρχεία JAR στην τσάντα των τεχνών τους είναι, "Πώς μπορώ να εξαγάγω μια εικόνα από ένα ΔΟΧΕΙΟ?" Θα απαντήσουμε σε αυτήν την ερώτηση και θα παράσχουμε μια τάξη για να είναι εξαιρετικά απλή η εξαγωγή οποιουδήποτε πόρου από ένα JAR!

Φόρτωση εικόνας GIF

Ας υποθέσουμε ότι έχουμε ένα αρχείο JAR που περιέχει μια δέσμη αρχείων εικόνας .gif που θέλουμε να χρησιμοποιήσουμε στην εφαρμογή μας. Δείτε πώς θα μπορούσαμε να αποκτήσουμε πρόσβαση σε ένα αρχείο εικόνας από το JAR χρησιμοποιώντας το JarResources:

 JarResources jar = νέο JarResources ("Images.jar"); Λογότυπο εικόνας = Toolkit.getDefaultToolkit (). CreateImage (jar.getResource ("logo.gif"); 

Αυτό το απόσπασμα κώδικα δείχνει ότι μπορούμε να δημιουργήσουμε ένα JarResources αντικείμενο που αρχικοποιήθηκε στο αρχείο JAR που περιέχει τον πόρο που μας ενδιαφέρει να χρησιμοποιήσουμε - Εικόνες.jar. Στη συνέχεια χρησιμοποιούμε το JarResources »getResource () μέθοδος για την παροχή ανεπεξέργαστων δεδομένων από το αρχείο logo.gif για τα εργαλεία εργαλείων AWT createImage () μέθοδος.

Μια σημείωση για την ονομασία

Το JarResource είναι ένα αρκετά απλό παράδειγμα του τρόπου χρήσης διαφόρων εγκαταστάσεων που παρέχονται από την Java 1.1 για χειρισμό αρχείων JAR και zip αρχείων.

Μια γρήγορη σημείωση για την ονομασία. Η υποστήριξη αρχειοθέτησης στην Java ξεκίνησε χρησιμοποιώντας τη δημοφιλή μορφή αρχειοθέτησης zip (ανατρέξτε στην ενότητα "Συμβουλή Java 21: Χρησιμοποιήστε αρχεία αρχειοθέτησης για να επιταχύνετε τη φόρτωση της μικροεφαρμογής"). Έτσι, αρχικά, κατά την εφαρμογή υποστήριξης Java για χειρισμό των αρχείων αρχειοθέτησης, όλες οι τάξεις και τα άλλα δεν τοποθετήθηκαν στο πακέτο java.util.zip. αυτά τα μαθήματα τείνουν να ξεκινούν με "ΦερμουάρΑλλά κάπου κατά τη μετάβαση στην Java 1.1, οι δυνάμεις που άλλαξαν το όνομα του αρχείου για να είναι πιο εστιασμένες στην Java. Ως εκ τούτου, αυτό που τώρα ονομάζουμε αρχεία JAR βασικά είναι αρχεία zip.

Πως δουλεύει

Τα σημαντικά πεδία δεδομένων για το JarResources Η κλάση χρησιμοποιείται για την παρακολούθηση και αποθήκευση του περιεχομένου του καθορισμένου αρχείου JAR:

δημόσια τελική τάξη JarResources {public boolean debugOn = false; ιδιωτικό Hashtable htSizes = νέο Hashtable (); ιδιωτικό Hashtable htJarContents = νέο Hashtable (); ιδιωτικό String jarFileName; 

Έτσι, το instantiation της κλάσης ορίζει το όνομα του αρχείου JAR και στη συνέχεια καλεί στο μέσα σε αυτό() μέθοδος για να κάνετε όλη την πραγματική εργασία:

 δημόσιο JarResources (String jarFileName) {this.jarFileName = jarFileName; μέσα σε αυτό(); } 

Τώρα το μέσα σε αυτό() Η μέθοδος φορτώνει σχεδόν ολόκληρο το περιεχόμενο του καθορισμένου αρχείου JAR σε ένα hashtable (προσπελάσιμο μέσω του ονόματος του πόρου).

Αυτή είναι μια αρκετά βαριά μέθοδος, οπότε ας το αναλύσουμε λίγο πιο μακριά. ο ZipFile Το μάθημα μας παρέχει βασική πρόσβαση στις πληροφορίες κεφαλίδας αρχείου JAR / zip. Αυτό είναι παρόμοιο με τις πληροφορίες καταλόγου σε ένα σύστημα αρχείων. Εδώ απαριθμούμε όλες τις καταχωρήσεις στο ZipFile και χτίστε το ht Μεγέθη hashtable με το μέγεθος κάθε πόρου στο αρχείο:

 ιδιωτικό κενό init () {δοκιμάστε {ZipFile zf = new ZipFile (jarFileName); Καταμέτρηση e = zf.entries (); ενώ (e.hasMoreElements ()) {ZipEntry ze = (ZipEntry) e.nextElement (); εάν (debugOn) {System.out.println (dumpZipEntry (ze)); } htSizes.put (ze.getName (), νέο Integer ((int) ze.getSize ())); } zf.close (); 

Στη συνέχεια, έχουμε πρόσβαση στο αρχείο μέσω της χρήσης του ZipInputStream τάξη. ο ZipInputStream Η τάξη κάνει όλη τη μαγεία για να μας επιτρέψει να διαβάσουμε κάθε έναν από τους μεμονωμένους πόρους στο αρχείο. Διαβάζουμε τον ακριβή αριθμό byte από το αρχείο που περιλαμβάνει κάθε πόρο και αποθηκεύουμε αυτά τα δεδομένα στο htJarContents hashtable προσβάσιμο με όνομα πόρου:

 FileInputStream fis = νέο FileInputStream (jarFileName); BufferedInputStream bis = νέο BufferedInputStream (fis); ZipInputStream zis = νέο ZipInputStream (bis); ZipEntry ze = null; ενώ ((ze = zis.getNextEntry ())! = null) {if (ze.isDirectory ()) {συνέχεια; } if (debugOn) {System.out.println ("ze.getName () =" + ze.getName () + "," + "getSize () =" + ze.getSize ()); } int size = (int) ze.getSize (); // -1 σημαίνει άγνωστο μέγεθος. if (size == - 1) {size = ((Integer) htSizes.get (ze.getName ())). intValue (); } byte [] b = νέο byte [(int) μέγεθος]; int rb = 0; int chunk = 0; ενώ (((int) μέγεθος - rb)> 0) {chunk = zis.read (b, rb, (int) μέγεθος - rb); εάν (chunk == - 1) {διάλειμμα; } rb + = κομμάτι; } // προσθήκη στον εσωτερικό πόρο 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 ("ολοκληρώθηκε."); } catch (FileNotFoundException e) {e.printStackTrace (); } catch (IOException e) {e.printStackTrace (); }} 

Σημειώστε ότι το όνομα που χρησιμοποιείται για την αναγνώριση κάθε πόρου είναι το όνομα διαδρομής με ειδική διαδρομή του πόρου στο αρχείο, δεν, για παράδειγμα, το όνομα μιας τάξης σε ένα πακέτο - δηλαδή, το ZipEntry κλάση από το πακέτο java.util.zip θα ονομάζεται "java / util / zip / ZipEntry" και όχι "java.util.zip.ZipEntry."

Το τελευταίο σημαντικό μέρος του κώδικα είναι το απλό πρόγραμμα οδήγησης δοκιμής. Το πρόγραμμα οδήγησης δοκιμής είναι μια απλή εφαρμογή που παίρνει ένα όνομα αρχείου JAR / zip και το όνομα ενός πόρου. Προσπαθεί να βρει τον πόρο στο αρχείο και αναφέρει την επιτυχία ή την αποτυχία του:

 public static void main (String [] args) ρίχνει το IOException {if (args.length! = 2) {System.err.println ("use: java JarResources"); System.exit (1); } JarResources jr = νέο JarResources (args [0]); byte [] buff = jr.getResource (args [1]); if (buff == null) {System.out.println ("Δεν ήταν δυνατή η εύρεση" + args [1] + "."); } αλλιώς {System.out.println ("Found" + args [1] + "(length =" + buff.length + ")."); }}} // Τέλος της κλάσης JarResources. 

Και εκεί το έχετε. Μια απλή στη χρήση τάξη που κρύβει όλη την ακαταστασία που σχετίζεται με τη χρήση πόρων που έχουν αποθηκευτεί σε αρχεία JAR.

Ασκήσεις για τον αναγνώστη

Τώρα που έχετε την αίσθηση για την εξαγωγή πόρων από ένα αρχείο αρχειοθέτησης, ακολουθούν ορισμένες οδηγίες που μπορεί να θέλετε να εξερευνήσετε κατά την τροποποίηση και την επέκταση του JarResources τάξη:

  • Αντί να φορτώνετε τα πάντα κατά την κατασκευή, καθυστερείτε τη φόρτωση. Στην περίπτωση ενός μεγάλου αρχείου JAR, ενδέχεται να μην υπάρχει αρκετή μνήμη για τη φόρτωση όλων των αρχείων κατά τη διάρκεια της κατασκευής.
  • Αντί απλώς να παρέχει μια γενική μέθοδο πρόσβασης όπως getResource (), θα μπορούσαμε να παρέχουμε άλλους ειδικούς πόρους πρόσβασης - για παράδειγμα, getImage (), που επιστρέφει μια Java Εικόνα αντικείμενο, getClass (), που επιστρέφει μια Java Τάξη αντικείμενο (με τη βοήθεια ενός προσαρμοσμένου φορτωτή κλάσης) και ούτω καθεξής. Εάν το αρχείο JAR είναι αρκετά μικρό, θα μπορούσαμε να προκατασκευάσουμε όλους τους πόρους βάσει των επεκτάσεών τους (.gif, .class και ούτω καθεξής).
  • Ορισμένες μέθοδοι πρέπει να παρέχουν πληροφορίες για το ίδιο το δεδομένο αρχείο JAR (βασικά ένα περιτύλιγμα ZipFile), συμπεριλαμβανομένων: ο αριθμός των καταχωρίσεων Jar / zip. έναν απαριθμητή που επιστρέφει όλα τα ονόματα των πόρων · αξεσουάρ που επιστρέφουν το μήκος (και άλλα χαρακτηριστικά) μιας συγκεκριμένης καταχώρησης · και ένα εξάρτημα που επιτρέπει την ευρετηρίαση, για να αναφέρουμε μερικά.
  • JarResources μπορεί να επεκταθεί για να χρησιμοποιηθεί από μικροεφαρμογές. Χρησιμοποιώντας τις παραμέτρους applet και το Σύνδεση URLC κατηγορία, το περιεχόμενο JAR μπορεί να ληφθεί από το δίκτυο αντί να ανοίξει τα αρχεία ως τοπικά αρχεία. Επιπλέον, μπορούμε να επεκτείνουμε αυτήν την τάξη ως προσαρμοσμένο πρόγραμμα διαχείρισης περιεχομένου Java.

συμπέρασμα

Εάν θέλετε να μάθετε πώς να εξαγάγετε μια εικόνα από ένα αρχείο JAR, τώρα έχετε έναν τρόπο. Όχι μόνο μπορείτε να χειριστείτε εικόνες με ένα αρχείο JAR, αλλά με τη νέα τάξη που παρέχεται σε αυτήν την συμβουλή, μπορείτε να επεξεργαστείτε τη μαγεία εξαγωγής όποιος πόρος από ένα JAR.

Ο Arthur Choi εργάζεται επί του παρόντος για την IBM ως συμβουλευτικός προγραμματιστής. Έχει εργαστεί σε διάφορες εταιρείες, όπως το SamSung Network Laboratory και το MITER. Τα διάφορα έργα στα οποία έχει εργαστεί είναι συστήματα πελατών / διακομιστών, υπολογιστής κατανεμημένων αντικειμένων και διαχείριση δικτύου. Έχει χρησιμοποιήσει διάφορες γλώσσες σε διάφορα περιβάλλοντα λειτουργικού συστήματος. Ξεκίνησε τον προγραμματισμό το 1981 με τους FORTRAN IV και COBOL. Αργότερα, άλλαξε σε C και C ++ και συνεργάζεται με την Java για περίπου δύο χρόνια. Ενδιαφέρεται περισσότερο για εφαρμογές της Java στους τομείς των αποθετηρίων δεδομένων μέσω δικτύων ευρείας περιοχής και παράλληλης και κατανεμημένης επεξεργασίας μέσω του Διαδικτύου (χρησιμοποιώντας προγραμματισμό με βάση πράκτορες). Ο John Mitchell, υπάλληλος, σύμβουλος και διευθυντής της δικής του εταιρείας, έχει επενδύσει τα τελευταία δέκα χρόνια στην ανάπτυξη προηγμένου λογισμικού υπολογιστών και στην παροχή συμβουλών και εκπαίδευσης άλλων προγραμματιστών. Έχει παράσχει συμβουλές σχετικά με την τεχνολογία Java, τους μεταγλωττιστές, τους διερμηνείς, τις εφαρμογές που βασίζονται στο Web και το εμπόριο μέσω Διαδικτύου. Ο John συνέγραψε το Making Sense of Java: Ένας οδηγός για τους διευθυντές και τους υπόλοιπους από εμάς και έχει δημοσιεύσει άρθρα σε περιοδικά προγραμματισμού. Εκτός από τη σύνταξη της στήλης Java Tips για το JavaWorld, εποπτεύει τις ομάδες συζήτησης comp.lang.tcl.announce και comp.binaries.geos.

Μάθετε περισσότερα σχετικά με αυτό το θέμα

  • Εδώ είναι το αρχείο τάξης JarResources.java //www.javaworld.com/javatips/javatip49/JarResources.java
  • JARs //www.javasoft.com/products/jdk/1.1/docs/guide/jar/index.html
  • Για περισσότερες πληροφορίες σχετικά με την υποστήριξη αρχειοθέτησης στην Java, ανατρέξτε στην ενότητα "Συμβουλή Java 21 Χρησιμοποιήστε αρχεία αρχειοθέτησης για να επιταχύνετε τη φόρτωση μικροεφαρμογών" //www.javaworld.com/javatips/jw-javatip21.html

Αυτή η ιστορία, "Java Tip 49: Πώς να εξαγάγετε πόρους Java από αρχεία JAR και zip" δημοσιεύτηκε αρχικά από την JavaWorld.