Java 檔案 (Java Archive, JAR) 文件是基于 Java
技術(shù)的打包方案。它們允許開發(fā)人員把所有相關(guān)的內(nèi)容 (.class、圖片、聲音和支持文件等) 打包到一個單一的文件中。JAR
文件格式支持壓縮、身份驗證和版本,以及許多其它特性。 如果你熟悉常見的 ZIP 格式,你會發(fā)現(xiàn) JAR 文件和它區(qū)別不大。JAR 文件提供了一個把多個文件打包到一個文件中的方法,而且被打包的每個文件都可以分別壓縮。JAR 文件可以添加一個被稱為 manifest 的東西,它們允許開發(fā)人員添加與內(nèi)容有關(guān)的其它信息。例如,manifest 可以指明由 JAR 文件中的哪一個文件開始運行應用程序,或者指定這個庫的版本等。 Java 2 SDK 標準版提供了一個 jar 工具,你可以通過它在控制臺下讀寫 JAR 文件。然后,也許有些時候你想在你的程序中讀寫 JAR 文件。(這篇技巧僅涉及了在程序中讀 JAR 文件的內(nèi)容。)非常高興,你可以做到,并且不需要考慮解壓的問題,因為類庫已經(jīng)幫你處理了。你要用到的類都在 java.util.jar 包中。這里要用到的主要的類是 JarFile 類,它是一個 .jar 文件自身的引用。其中的每個文件則由 JarEntry 引用。 現(xiàn)在開始,傳遞一個參數(shù)給 JarFile 的構(gòu)造函數(shù)創(chuàng)建一個 JarFile 實例,這個參數(shù)可能是 String 也可以是 File,它是一個 .jar 文件的位置: JarFile jarFile = new JarFile("thefile.jar"); 或者 File file = new File("thefile.jar"); JarFile jarFile = new JarFile(file); 它還有其它一些構(gòu)造函數(shù),支持身份驗證和標記文件為刪除。不過這里不會涉及到這些構(gòu)造函數(shù)。 在你得到一個 JAR 文件的引用之后,你就可以讀了其內(nèi)容的目錄了。JarFile 的 entries 方法返回一個所有條目的 Enumeration 對象,你還可以從 manifest 文件中獲得它的屬性、身份驗證信息以及其它的信息,如條目的名稱和大小。 Enumeration enum = jarFile.entries(); while (enum.hasMoreElements()) { process(enum.nextElement()); } 以前提到過,每個個體都是一個 JarEntry。這個類有一些諸如 getName、getSize 和getCompressedSize 的方法。 記我們舉例說明如何在程序中使用這些特性。下面的程序顯示 JAR 文件的內(nèi)容列表及各項的名稱、大小和壓縮后的大小。(這很類似于使用帶 "t" 和 "v" 參數(shù)的 jar 命令。) import java.io.*; import java.util.*; import java.util.jar.*; public class JarDir { public static void main (String args[]) throws IOException { if (args.length != 1) { System.out.println("Please provide a JAR filename"); System.exit(-1); } JarFile jarFile = new JarFile(args[0]); Enumeration enum = jarFile.entries(); while (enum.hasMoreElements()) { process(enum.nextElement()); } } private static void process(Object obj) { JarEntry entry = (JarEntry)obj; String name = entry.getName(); long size = entry.getSize(); long compressedSize = entry.getCompressedSize(); System.out.println(name + "\t" + size + "\t" + compressedSize); } } 如果你用 J2SE 1.4.1 中的 jce.jar 來試驗上述的 JarDir 程序,你應該看像下面那樣的輸出 (在 ... 處應該顯示更多文件): META-INF/MANIFEST.MF 5315 1910 META-INF/4JCEJARS.SF 5368 1958 META-INF/4JCEJARS.DSA 2207 1503 META-INF/ 0 2 javax/ 0 0 javax/crypto/ 0 0 javax/crypto/interfaces/ 0 0 javax/crypto/interfaces/DHKey.class 209 185 javax/crypto/interfaces/DHPublicKey.class 265 215 javax/crypto/interfaces/DHPrivateKey.class 267 215 javax/crypto/interfaces/PBEKey.class 268 224 javax/crypto/SecretKey.class 167 155 ... 注意輸入內(nèi)容頂部包含 META-INF 的那幾行,這是 menifest 和安全驗證信息。其中大小為 0 的條目不是文件,而是目錄。 要真正從 JAR 文件中讀取文件內(nèi)容,你必須獲得相應條目的 InputStream。這不同于 JarEntry。JarEntry 僅包括了入口信息,卻并未包含實際的內(nèi)容。這很像 File 和 FileInputSteram 的區(qū)別。只訪問 File,永遠不會打開相應的文件,它只讀取在目錄中的信息。下面告訴你如何從一個條目得到 InputStream: InputStream input = jarFile.getInputStream(entry); 得到輸入流之后,你只需要像讀其它流一樣讀它就行了。如果是一個文本流,要記得使用一個 Reader 來從流中獲取字符。而對于字節(jié)流,如圖片,則只好直接讀取。 下面的程序演示了從一個 JAR 文件中讀取內(nèi)容。運行程序時,需要指定要從 JAR 文件中讀取的文件名,這個文件必須是文本文件類型。 import java.io.*; import java.util.jar.*; public class JarRead { public static void main (String args[]) throws IOException { if (args.length != 2) { System.out.println("Please provide a JAR filename and file to read"); System.exit(-1); } JarFile jarFile = new JarFile(args[0]); JarEntry entry = jarFile.getJarEntry(args[1]); InputStream input = jarFile.getInputStream(entry); process(input); jarFile.close(); } private static void process(InputStream input) throws IOException { InputStreamReader isr = new InputStreamReader(input); BufferedReader reader = new BufferedReader(isr); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } reader.close(); } } 假設你有一個名為 myfiles.jar 的 JAR 文件,其中有一個名為 spider.txt 文本文件,再假設那個 pider.txt 包含如下文本: The itsy bitsy spider Ran up the water spout Down came the rain and Washed the spider out 運行下面的命令以顯示 JAR 文件中該文本文件的內(nèi)容: java JarRead myfiles.jar spider.txt |
|