2013-10-13 66 views
5

所以我試圖通過檢查mainfest文件中的一些值來查看.jar​​是否有效。使用java讀取和解析文件的最佳方法是什麼?我想使用此命令提取文件使用Java讀取.jar清單文件

jar -xvf anyjar.jar META-INF/MANIFEST.MF 

,但我可以這樣做:

File manifest = Command.exec("jar -xvf anyjar.jar META-INF/MAINFEST.MF"); 

然後使用一些緩衝的讀者或東西來解析文件的行?

感謝您的幫助......

+0

的可能的複製http://stackoverflow.com/questions/2198525/can-values-defined-in-manifest-mf-be-accessed-programmatically/2198542 –

回答

8

與使用jar工具的問題是,它需要完整的JDK安裝。 Java的許多用戶只會安裝JRE,其中不包括jar

而且,jar必須位於用戶的PATH上。

所以不是我會建議使用合適的API,像這樣:

Manifest m = new JarFile("anyjar.jar").getManifest(); 

這實際上應該是更容易!

+0

哦,哇,這更有意義。等等,我也使用Command.exec(「提取jar的代碼」)。有沒有更簡單的方法來做到這一點。 – Kyle

+0

是的。但是在Stackoverflow上一定有個問題。 –

+0

到目前爲止,我將能夠找到正在使用命令提示符,但這個鏈接似乎可以工作,但它看起來有點像大聲笑。爲什麼不能像jarfile.run()之類的簡單。 http://www.programcreek.com/2012/08/unzip-a-jar-file-in-java-program/ – Kyle

4

包類在 java.lang.Package有方法來做你想做的。這裏有一個簡單的方法使用Java代碼來獲得清單內容:

String t = this.getClass().getPackage().getImplementationTitle(); 
String v = this.getClass().getPackage().getImplementationVersion(); 

我把這個變成一個共享的實用class.The方法的靜態方法接受一個手柄類對象作爲參數。這樣,我們系統中的任何類都可以在需要時獲取自己的清單信息。顯然,該方法可以很容易地修改,以返回值的數組或哈希表。

調用方法:

String ver = GeneralUtils.checkImplVersion(this); 

在一個名爲 GeneralUtils.java文件的方法:

public static String checkImplVersion(Object classHandle) 
{ 
    String v = classHandle.getClass().getPackage().getImplementationVersion(); 
    return v; 
} 

而獲得比那些你可以通過包裝獲得其他領域的表現值(例如你自己的建造日期),你得到主要屬性並且通過那些工作,尋求你想要的特定的一個。下面的代碼是我發現的類似問題中的一個輕微的mod,可能是在這裏。 (我想貸,但我失去了它 - 對不起)

把這個在一個try-catch塊,傳遞一個classHandle(以下簡稱「本」或MyClass.class)的方法。 「classHandle」 是一個Class類型:

String buildDateToReturn = null; 
    try 
    { 
    String path = classHandle.getProtectionDomain().getCodeSource().getLocation().getPath(); 
    JarFile jar = new JarFile(path); // or can give a File handle 
    Manifest mf = jar.getManifest(); 
    final Attributes mattr = mf.getMainAttributes(); 
    LOGGER.trace(" --- getBuildDate: " 
      +"\n\t path:  "+ path 
      +"\n\t jar:  "+ jar.getName() 
      +"\n\t manifest: "+ mf.getClass().getSimpleName() 
      ); 

    for (Object key : mattr.keySet()) 
    { 
     String val = mattr.getValue((Name)key); 
     if (key != null && (key.toString()).contains("Build-Date")) 
     { 
      buildDateToReturn = val; 
     } 
    } 
    } 
    catch (IOException e) 
    { ... } 

    return buildDateToReturn; 
+0

關於Package方法,必須使用正確的名稱(例如「Implementation-Version」)在Manifest中定義這些名稱,這些名稱可以在類java.util.jar.Attributes.Name中找到。這不是特別好記錄。 –

0

最簡單的方法是使用JarURLConnection類:

String className = getClass().getSimpleName() + ".class"; 
String classPath = getClass().getResource(className).toString(); 
if (!classPath.startsWith("jar")) { 
    return DEFAULT_PROPERTY_VALUE; 
} 

URL url = new URL(classPath); 
JarURLConnection jarConnection = (JarURLConnection) url.openConnection(); 
Manifest manifest = jarConnection.getManifest(); 
Attributes attributes = manifest.getMainAttributes(); 
return attributes.getValue(PROPERTY_NAME); 

因爲在某些情況下...class.getProtectionDomain().getCodeSource().getLocation();給人以vfs:/路徑,所以這應該是另外處理。

或者,用的ProtectionDomain:

File file = new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI()); 
if (file.isFile()) { 
    JarFile jarFile = new JarFile(file); 
    Manifest manifest = jarFile.getManifest(); 
    Attributes attributes = manifest.getMainAttributes(); 
    return attributes.getValue(PROPERTY_NAME); 
}