天天看點

從 Java 檔案(JAR) 中讀取檔案

Java 檔案 (Java Archive, JAR) 檔案是基于 Java 技術的打包方案。它們允許開發人員把所有相關的内容 (.class、圖檔、聲音和支援檔案等) 打包到一個單一的檔案中。JAR 檔案格式支援壓縮、身份驗證和版本,以及許多其它特性。

  從 JAR 檔案中得到它所包含的檔案内容是件棘手的事情,但也不是不可以做到。這篇技巧就将告訴你如何從 JAR 檔案中取得一個檔案。我們會先取得這個 JAR 檔案中的檔案目錄,然後讀取指定的檔案。

  如果你熟悉常見的 ZIP 格式,你會發現 JAR 檔案和它差別不大。JAR 檔案提供了一個把多個檔案打包到一個檔案中的方法,而且被打包的每個檔案都可以分别壓縮。JAR 檔案可以添加一個被稱為 manifest 的東西,它們允許開發人員添加與内容有關的其它資訊。例如,manifest 可以指明由 JAR 檔案中的哪一個檔案開始運作應用程式,或者指定這個庫的版本等。

  Java 2 SDK 标準版提供了一個 jar 工具,你可以通過它在控制台下讀寫 JAR 檔案。然後,也許有些時候你想在你的程式中讀寫 JAR 檔案。(這篇技巧僅涉及了在程式中讀 JAR 檔案的内容。)非常高興,你可以做到,并且不需要考慮解壓的問題,因為類庫已經幫你處理了。你要用到的類都在 java.util.jar 包中。這裡要用到的主要的類是 JarFile 類,它是一個 .jar 檔案自身的引用。其中的每個檔案則由 JarEntry 引用。

  現在開始,傳遞一個參數給 JarFile 的構造函數建立一個 JarFile 執行個體,這個參數可能是 String 也可以是 File,它是一個 .jar 檔案的位置:

JarFile jarFile = new JarFile("thefile.jar");

或者

File file = new File("thefile.jar");

JarFile jarFile = new JarFile(file);

  它還有其它一些構造函數,支援身份驗證和标記檔案為删除。不過這裡不會涉及到這些構造函數。

  在你得到一個 JAR 檔案的引用之後,你就可以讀了其内容的目錄了。JarFile 的 entries 方法傳回一個所有條目的 Enumeration 對象,你還可以從 manifest 檔案中獲得它的屬性、身份驗證資訊以及其它的資訊,如條目的名稱和大小。

// 譯者注:enum 在 Java 5.0 中是關鍵字,是以該例在 5.0 中應該編譯失敗  

// 但英文原著發表于 Java 5.0 出現之前,是以可以使用 enum 作變量名  

// 為忠于原著,這裡未作修改  

Enumeration enum = jarFile.entries();  

while (enum.hasMoreElements()) {  

    process(enum.nextElement());  

以前提到過,每個個體都是一個 JarEntry。這個類有一些諸如 getName、getSize 和getCompressedSize 的方法。

讓我們舉例說明如何在程式中使用這些特性。下面的程式顯示 JAR 檔案的内容清單及各項的名稱、大小和壓縮後的大小。(這很類似于使用帶 "t" 和 "v" 參數的 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 + " " + size + " " + 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

...

注意輸入内容頂部包含 META-INF 的那幾行,這是 menifest 和安全驗證資訊。其中大小為 0 的項不是檔案,而是目錄。

要真正從 JAR 檔案中讀取檔案内容,你必須獲得相應條目的 InputStream。這不同于 JarEntry。JarEntry 僅包括了入口資訊,卻并未包含實際的内容。這很像 File 和 FileInputSteram 的差別。隻通路 File,永遠不會打開相應的檔案,它隻讀取在目錄中的資訊。下面告訴你如何從一個條目得到 InputStream:

InputStream input = jarFile.getInputStream(entry);

得到輸入流之後,你隻需要像讀其它流一樣讀它就行了。如果是一個文本流,要記得使用一個 Reader 來從流中擷取字元。而對于位元組流,如圖檔,則隻好直接讀取。

下面的程式示範了從一個 JAR 檔案中讀取内容。運作程式時,需要指定要從 JAR 檔案中讀取的檔案名,這個檔案必須是文本檔案類型。

public class JarRead ...{  

        if (args.length != 2) ...{  

            System.out.println("Please provide a JAR filename and file to read");  

        JarEntry entry = jarFile.getJarEntry(args[1]);  

        InputStream input = jarFile.getInputStream(entry);  

        process(input);  

        jarFile.close();  

    private static void process(InputStream input)   

        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 檔案中該文本檔案的内容:

java JarRead myfiles.jar spider.txt

本文轉自邊城__ 51CTO部落格,原文連結:http://blog.51cto.com/jamesfancy/843235,如需轉載請自行聯系原作者