從JAR文件中讀取文件

  版權聲明:可以任意轉載,轉載時請務必以超鏈接形式標明文章原始出處和作者信息及本聲明 
  
  作者:John Zukowski 
  翻譯:Roger Sun 
  原文來源: 
  http://developer.java.sun.com/developer/JDCTechTips/2003/tt0122.html#1 
  譯文地址: 
  http://www.ydtx.com/cgi-bin/forum/topic.cgi?forum=27&topic=8 
  
  ==============================================
  
  JAR文件是打包基於JAVA技術的解決方案的標準方法。它允許開發者將所有相關內容(.class、圖片、聲音、及所有支持的文件)打包到一個文件中。JAR格式支持壓縮、認證、版本號及其他很多特性。 
  
  從JAR文件中讀取文件是很麻煩的事情,但是也不一定全是這樣。本文將告訴你如何從JAR文件中讀取文件,首先,得到JAR文件中的文件目錄,然後在進行具體的某一個文件的操作。 
  
  如果你對於常用的ZIP格式比較熟悉的話,JAR文件也就差不多。JAR文件提供一種將多個文件打包到一個文件中的方法,其中每一個文件可能獨立地被壓縮。JAR文件所增加的內容是manifest,它允許開發者可以提供附加的關於內容的信息。例如,manifest表明JAR文件中的哪個文件是用來運行一個程序的,或者庫的版本號等 
  
  J2SEDK提供了一個jar工具,你可以用它從控制檯讀寫JAR文件。然而,如果你需要在程序中代碼讀寫JAR文件,可能需要一點時間(本文只包含如何在程序中讀寫JAR文件)。好消息是你可以做到這一點,而且你不用擔心解壓的事,因爲類庫將幫助你完成這些。你所需要的類文件位於java.util.jar包中。這裏主要的類是JarFile,它是.jar文件自身的一個引用。較大文件中的每一個單獨的文件是通過一個JarEntry引用的。 
  
  首先,通過把將JAR文件位置傳給構造函數,創建一個JarFile的實例,位置可能是String或File的形式,如下: 
    JarFile jarFile = new JarFile("thefile.jar"); 
  
  或者: 
  
    File file = new File("thefile.jar"); 
    JarFile jarFile = new JarFile(file); 
  
  
  你可能注意到當文件不在class path中時,JarFile類對於從JAR中讀取文件文件是很有用的。 
  當你想指定目標JAR文件時,JarFile類對於從JAR中讀取文件同樣也很有用。當然,如果JAR文件在class path中,從其中讀取文件的方法比較簡單,你可以用下面的方法: 
  
   URL url = ClassLoader.getSystemResource(name); 
  或者 
  
   InputStream stream = 
     ClassLoader.getSystemResourceAsStream(name); 
  
  這種技術允許你從在class path中的JAR文件裏讀取文件。你不必指定JAR文件名。 
  
  
  還有其他的構造函數,如認證支持,標誌要刪除的文件等。這些構造函數在這兒不做說明。 
  
  當你有了該JAR文件的一個引用之後,你就可以讀取其文件內容中的目錄信息了。JarFile的entries方法返回所有entries的枚舉集合(Enumeration)。通過每一個entry,你可以從它的manifest文件得到它的屬性,任何認證信息,以及其他任何該entry的信息,如它的名字或者大小等。 
  
   Enumeration enum = jarFile.entries(); 
   while (enum.hasMoreElements()) { 
    process(enum.nextElement()); 
   } 
  
  正如前面提到的,每一個entry是一個JarEntry。該類有getName,getSize,getCompressedSize等方法。 
  
  下面,讓我們舉例說明在程序中如何使用這些特性。下面的程序顯示你指定的JAR文件中內容的名稱,大小,壓縮大小等(這有點類似於在使用jar命令時,指定"t"和"v"選項)。 
  
   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); 
    } 
   } 
  
  如果你用J2SE1.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行。這是manifest和安全認證信息。0字節的entries不是文件,但是有點相當於目錄。 
  
  爲了從JAR文件中真正讀取一個指定的文件,你必須到其entry的InputStream。這和JarEntry不一樣。這是因爲JarEntry只是包含該entry的有關信息,但是並不實際包含該entry的內容。這和File和FileInputStream的區別有點兒相似。訪問文件沒有打開文件,它只是從目錄中讀取了該文件的信息。下面是如何得到entry的InputStream: 
  
   InputStream input = jarFile.getInputStream(entry); 
  
  當你有了輸入流,你就可以像讀取其他流一樣讀取它。在文本流中(text stream),記得使用讀取器(Reader)從流中取得字符。對於面向字節的流,如圖片文件,直接讀取就行了。 
  
  下面的程序演示如何從JAR文件中讀取文件。指定JAR文件的名稱,要讀取的文件的名稱(打包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文件中有一個spider.txt文件,spider文件的內容如下: 
  
   The itsy bitsy spider 
   Ran up the water spout 
   Down came the rain and 
   Washed the spider out 
  
  你可以通過下面的命令來顯示該文本文件的內容: 
  
   java JarRead myfiles.jar spider.txt  
  
  有關JAR文件的更多內容,請參考JAR文件規範

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章