2016-06-19 100 views
2

我的代碼在JAR文件中運行,我需要獲取該文件的完整路徑。 例如,我的JAR名爲example.jar,位於D:\ example \ 因此,我需要通過該jar內的一些代碼來獲取「D:\ example \ example.jar」。 我已經嘗試了很多方法來獲得該路徑,但他們都沒有正常工作。獲取正在運行的JAR文件的路徑返回「rsrc:./」

其中之一是

getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath() 

很多人說,這爲他們工作,但它返回「RSRC:./」對我來說。

我已搜查後,我發現我的MANIFEST.MF包含此:

Manifest-Version: 1.0 
Rsrc-Class-Path: ./ 
Class-Path: . 
Rsrc-Main-Class: Example 
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader 

我不知道這意味着什麼,但如果我刪除RSRC東西,取代其他的事情吧,它說罐子壞了。我認爲這是它不起作用的原因。有人知道這意味着什麼嗎? PS:我正在使用BAT文件運行我的JAR。

+1

爲什麼要獲取JAR的路徑? – SJuan76

+1

'getPath()'*不會將URI轉換爲文件。即使它是一個file:URI,路徑部分可能包含百分號轉義符,所以使用getPath()最終將返回一個不是有效文件名的字符串。將URI轉換爲文件名的正確方法是'Paths.get(uri)',但它只適用於file:URI。也就是說,無論你想要做什麼,都可以使用Class.getResource或ClassLoader.getResource來完成。 – VGR

+0

你可以得到一個jar本身的路徑,但是談論jar文件中的文件路徑是沒有意義的。 – MeBigFatGuy

回答

0

我剛剛創建了一個新的工作區和感動每一個項目到它,一切工作正常,現在,我認爲這是一個錯誤或東西...謝謝大家的幫助!

0

根據您的意見,看起來您真正的問題是如何從應用程序.jar中複製文件。你可以做到這一點是這樣的:

String jarEntry = "/files/data.txt"; 
Path destination = Paths.get(
    System.getProperty("user.home"), "Downloads", "data.txt"); 

try (InputStream stream = getClass().getResourceAsStream(jarEntry)) { 
    Files.copy(stream, destination); 
} 

Class.getResource和Class.getResourceAsStream從classpath中讀取數據,通常作爲一個.jar文件是在類路徑中,入口如你自己的應用程序。 jar文件。

嵌入類路徑中的文件通常稱爲應用程序資源或簡稱爲「資源」。始終使用正斜槓(/)作爲目錄分隔符在所有平臺(甚至是Windows)上指定資源。

如果你不知道你應該通過什麼樣的字符串的getResource或的getResourceAsStream,檢查你的.jar文件的內容。

+0

我有一個工作方法來複制這些文件夾和文件,我只需要我的JAR文件的路徑來讀出它的條目。我無法使用你的方法,因爲有太多的文件需要手工輸入路徑。 – Doenerstyle

+0

爲什麼不打開終端窗口或命令窗口,請輸入類似'dir/b'(在Windows)或'ls -1'(其他操作系統)中的命令,然後將輸出複製並粘貼到代碼中,然後在其中對其進行格式化作爲一個字符串數組?您也可以在構建完成後在您的.jar文件中執行'jar tf'。 – VGR

0
package com.example; 

import java.io.BufferedInputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.net.URL; 
import java.util.jar.JarEntry; 
import java.util.jar.JarInputStream; 

public class HomeJar { 

    public static void main(String[] args) throws IOException { 

     URL u = HomeJar.class.getProtectionDomain().getCodeSource().getLocation(); 

     File f = new File(u.getPath().toString()); 

     if (!f.isFile()) { 
      throw new RuntimeException("'" + u + "' isn't a jar"); 
     } 

     try (JarInputStream jis = new JarInputStream(new BufferedInputStream(new FileInputStream(f)))) { 
      JarEntry je = jis.getNextJarEntry(); 
      while (je != null) { 
       System.out.println(je.getName()); 
       je = jis.getNextJarEntry(); 
      } 
     } 
    } 

} 
+0

如果我運行這個類,它會拋出一個由RuntimeException引起的InvocationTargetException異常,並且它還說'「rsrc:./」不是一個jar「,所以它和我的問題一樣。 – Doenerstyle

+0

你使用的是什麼jdk? – MeBigFatGuy

+0

8更新77(64位) – Doenerstyle

3

我絆了這個問題也是一樣,離開這裏我調查的人問自己在未來的rsrc手段是什麼誰。

我正在使用Eclipse Mars 1並嘗試將我的項目導出爲可運行JAR。在那裏,我可以選擇庫處理和之間做出選擇:

  • 包所需的庫

    1. 提取所需的庫到生成的JAR到生成JAR
    2. 複製所需的庫到一個子文件夾旁邊的生成JAR

    的線將被測試是

    System.out.println(MyClass.class.getProtectionDomain().getCodeSource().getLocation()); 
    

    的JAR FIL e的名字是MyJar。jar(將放在桌面上),項目的名稱和文件夾是MyProject。

    結果:

    1. file:/C:/Users/admin/Desktop/MyJar.jar
    2. rsrc:./
    3. file:/C:/Users/admin/Desktop/MyJar.jar
    4. <意味着在Eclipse > file:/C:/Development/workspace/MyProject/target/classes/

    運行我寫了一個舒適的方法爲:

    public class SystemUtils { 
    
        /** 
        * Let no one instanciate this class. 
        */ 
        private SystemUtils() {} 
    
        /** 
        * If the current JVM was started from within a JAR file. 
        * @return <code>Boolean.TRUE</code> if it is, <code>Boolean.FALSE</code> if it is not, <code>null</code> if unknown. 
        */ 
        public static Boolean executedFromWithinJar() { 
         Boolean withinJar = null; 
         try { 
          String location = SystemUtils.class.getProtectionDomain().getCodeSource().getLocation().toString(); 
          if (location.startsWith("rsrc:") 
           || location.endsWith(".jar") && !new File(location.substring(location.indexOf(':') + 1)).isDirectory()) 
           withinJar = Boolean.TRUE; 
          else 
           withinJar = Boolean.FALSE; 
         } 
         catch (Exception ex) {/* value is still null */} 
         return withinJar; 
        } 
    
    } 
    
  • +0

    非常感謝GreenThor,經過幾個小時的搜索後,我解決了這個問題。 – dariusiv

    相關問題