2014-04-24 73 views
1

我有一個程序使用的庫。該庫在資源文件夾中加載一個特殊的目錄。如何訪問Java中的調用程序的資源目錄

在庫

我有方法

public class DataRegistry{ 

    public static File getSpecialDirectory(){ 
     String resourceName = Thread.currentThread().getContextClassLoader().getResource("data").getFile().replace("%20", " "); 
     File file = new File(resourceName); 
     return file; 
    } 

} 
在我的程序

我的主要方法

public static void main(String args[]){ 
    System.out.println(Data.getSpecialDirectory()); 
} 

當我的數據程序內執行getSpecialDirectory()在JUnit測試,該資源被提取並且一切都很好。

當我在數據程序(導入jar)之外的主要方法中執行getSpecialDirectory()時,我得到jars數據目錄,而不是執行線程的程序所期望的目錄。

我覺得得到父類加載器將解決這個問題......我相信我可能在我的理解這裏有一個基本問題。

爲清楚:https://gist.github.com/AnthonyClink/11275442

(用法) 行此文件的31: https://gist.github.com/AnthonyClink/11275661

我的勁歌可能有一些做

(庫) 行此文件的15它,所以分享它們可能很重要:\

(Library) https://github.com/Clinkworks/Neptical/blob/master/pom.xml

(用法) https://github.com/Clinkworks/Neptical-Maven-Plugin/blob/master/pom.xml

+0

什麼是你想acheive?獲取相對於DataMojo類的文件夾的路徑? – tgkprog

回答

1
  1. 你想在Java程序從加載目錄?可以試試

    文件f = new File(「。」)。getCanconicalFile();

  2. 或者,如果你想如果你想相對於從那裏您的類加載的jar目錄中的所有地方可以嘗試解析來自System.env類路徑或使用默認的類加載器

  3. :從報價http://www.nakov.com/blog/2008/06/11/finding-the-directory-where-your-java-class-file-is-loaded-from/

    URL classesRootDir = getClass()。getProtectionDomain()。getCodeSource()。getLocation();

以上的回報加載你的.class 文件時使用的基本目錄。它不包含軟件包。它僅包含類路徑 目錄。例如,在一個控制檯應用程序的上述 返回成才這樣的:

文件:/ C:/文件%20於是%20Settings /管理員/工作區/ TestPrj/bin中/

在Web應用它返回成纔像這樣:

文件:/ C:/ Tomcat的/ webapps /下MyApp的/ WEB-INF /班/

僅供參考,如果運行程序的用戶ID不能讀取所有文件夾這可能適用:http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getProtectionDomain%28%29

  1. 或通過調用類的一個.class對象作爲參數,並得到其類加載器
+1

您永遠不應該使用java.io.File對象來讀取jar資源或web資源的內容。這依賴於應用程序服務器在部署時爆炸WAR文件 - 而且它們中的許多人根本就沒有這樣做。 servlet和JDK API爲此提供了其他機制。 –

+0

這是怎麼回事? 「getClass()。getProtectionDomain()。getCodeSource()。getLocation()」可能是一場戰爭?猜測需要檢查文件對象是一個文件還是一個目錄,並採取父母? – tgkprog

+0

不知道新的文件(「。」)是非常靈活的謝謝你。 – AnthonyJClink

0

雖然用戶@t​​gkprog是正確的,他的回答是正確的,我很難想象你真的想你好像什麼(3)中已經詢問和正確回答了什麼。請編輯您的問題,並解釋

  • 輸出應該是什麼樣子,如果resourceName將被打印到控制檯,
  • ,如果你真的想要的JAR文件的位置(在我的測試情況下會是這樣的文件:/ C:/Users/Alexander/.m2/repository/com/clinkworks/neptical/0.0.1-SNAPSHOT/data,這是沒有意義的,因爲你不想讀取甚至寫入本地Maven緩存),
  • 或者您可能更想直接從JAR文件或任何其他位置(如當前工作目錄等)讀取資源。

否則恐怕沒有好的方法來回答這個問題。

+0

我認爲這將是在本地Maven的緩存,如果你從IDE內運行......在已部署的應用程序可以是任意目錄,只要你加入到classpath中 – tgkprog

+0

那麼這條道路,穩定的解決方案應該在所有環境中工作,不要假設一個特定的運行時部署場景 - 至少沒有一個原始海報甚至沒有描述過。因此我的詢問作了更詳細的解釋。 – kriegaex

5
  1. Maven使用target/classes和target/test-classes目錄來編寫用於運行單元測試的類路徑。將src/main/resources和src/test/resources的內容與編譯的java源文件(.class文件)一起復制到這些位置。
  2. java.lang.ClassLoader.getResource返回java.net.URL
  3. 在單元測試的情況下,ClassLoader.getResource返回一個file:// schemed URL,並且您的代碼按預期工作。
  4. 當您的代碼在打包到jar文件中時執行時,ClassLoader.getResource不再返回文件:// schemed URL。它不能因爲資源不再是文件系統中的獨立實體 - 它被埋在了jar文件中。你實際得到的是一個jar:file:// schemed URL。
  5. jar:無法通過[java.io.File]對象訪問URL。

如果您只需要讀取資源的內容,您應該使用java.lang.ClassLoader.getResourceAsStream(...)並從中讀取內容。

請注意,不能更新類加載器資源的內容。

+0

我認爲他想父文件夾,然後抓住這是相對於該文件夾的一些其他資源 - 在一個子目錄稱爲數據 – tgkprog

+0

+1。關於爲什麼不能這樣做的詳細解釋。 – Jayan

+0

沒錯,這是隻讀......但是我的問題是不知道如何讀取數據流,但如何獲取文件的URL。我正在使用maven,並且按照慣例我期望圖書館的用戶使用maven。 Maven確實編譯了這些資源,並且我不想將這些資源鏈接到jar文件,我想要用戶應用程序類root的url。由於圖書館在一個罐子裏,我似乎無法瞄準正確的目錄。如果您可以幫助我定位該目錄,我將非常樂意接受這個詳細的答案。 – AnthonyJClink

1

就我所知,無法保證您擁有資源目錄。 Java提供獲取資源的方法爲InputStream,但沒有任何方法可以輕鬆地獲取資源的文件,但對於給定的資源可能需要get the URL

如果你需要在你的應用程序中的特殊工作目錄,我推薦,作爲一個系統屬性,程序參數,一個Web應用程序參數,還是其他什麼東西,可以讓你知道你的應用程序文件通過。您甚至可以使用作爲資源包含在您的應用程序中的ZIP文件填充此目錄,因爲Java中的ZIP庫確實接受輸入流作爲參數。

相關問題