2012-10-09 45 views
0

我有一個用例,我需要將這段代碼導出爲一個Java庫(最終將成爲JAR),但問題在於它需要使用一段信息存儲在文件系統上的物理文件中。內部JAR使用文件系統上的文件

我有2個問題在這裏:

1)我應該在哪裏穿上,我能想到的是在包含庫中的Java模塊的資源目錄中的文件系統(一種選擇這些文件:有一個疑問,雖然資源目錄是否也被編譯到jar中?)

2)當我從外部Java應用程序使用該庫時,庫如何能夠找到這些文件?他們仍然會在類路徑中嗎?

+0

能有什麼文件呢?配置文件?該文件是否應該被覆蓋? –

+0

目前還不清楚您是否想用JAR移動文件(使用'getResourceAsStream'),或者文件獨立於JAR(指定用戶可編輯的.properties中的路徑/將其作爲啓動參數傳遞,通過註銷來回答) – SJuan76

+0

@ Pierre-HenriToussaint - 是的,你可以把它當作一個配置文件,但是我想問的一點是:讓我們把它的範圍擴展到我需要暴露給各種應用程序的類。這些類需要訪問這些配置文件(並且這些類是獨立於使用類的應用程序而固定的)。當這個jar被導入到應用程序,並且應用程序嘗試使用上面提到的jar中的一個類來嘗試從配置文件中檢索一些信息時,是否所有東西都能正常工作,沒有任何類路徑問題? –

回答

0

我發現了一個相關的答案的另一個問題的一部分:How to load a folder from a .jar?

我可以使用下面的代碼成功地檢索文件:

/** 
    * List directory contents for a resource folder. Not recursive. 
    * This is basically a brute-force implementation. 
    * Works for regular files and also JARs. 
    * 
    * @author Greg Briggs 
    * @param clazz Any java class that lives in the same place as the resources you want. 
    * @param path Should end with "/", but not start with one. 
    * @return Just the name of each member item, not the full paths. 
    * @throws URISyntaxException 
    * @throws IOException 
    */ 
    String[] getResourceListing(Class clazz, String path) throws URISyntaxException, IOException { 
     URL dirURL = clazz.getClassLoader().getResource(path); 
     if (dirURL != null && dirURL.getProtocol().equals("file")) { 
     /* A file path: easy enough */ 
     return new File(dirURL.toURI()).list(); 
     } 

     if (dirURL == null) { 
     /* 
     * In case of a jar file, we can't actually find a directory. 
     * Have to assume the same jar as clazz. 
     */ 
     String me = clazz.getName().replace(".", "/")+".class"; 
     dirURL = clazz.getClassLoader().getResource(me); 
     } 

     if (dirURL.getProtocol().equals("jar")) { 
     /* A JAR path */ 
     String jarPath = dirURL.getPath().substring(5, dirURL.getPath().indexOf("!")); //strip out only the JAR file 
     JarFile jar = new JarFile(URLDecoder.decode(jarPath, "UTF-8")); 
     Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar 
     Set<String> result = new HashSet<String>(); //avoid duplicates in case it is a subdirectory 
     while(entries.hasMoreElements()) { 
      String name = entries.nextElement().getName(); 
      if (name.startsWith(path)) { //filter according to the path 
      String entry = name.substring(path.length()); 
      int checkSubdir = entry.indexOf("/"); 
      if (checkSubdir >= 0) { 
       // if it is a subdirectory, we just return the directory name 
       entry = entry.substring(0, checkSubdir); 
      } 
      result.add(entry); 
      } 
     } 
     return result.toArray(new String[result.size()]); 
     } 

     throw new UnsupportedOperationException("Cannot list files for URL "+dirURL); 
    } 
0

您可以傳遞屬性文件中的文件位置或某種技術。

0

我應該在哪裏放於文件系統

這是由你來決定,雖然這將是一個好主意,使這個配置這些文件。嘗試適應主機操作系統/發行版的慣例也是一個好主意,雖然這些會有所不同......並取決於應用程序的性質。

當我從外部Java應用程序使用此庫時,庫如何能夠找到這些文件?

您通常會使用配置屬性或初始化參數來保存/傳遞位置。如果你正在編寫一個應用程序而不是一個庫,那麼你可以使用Java Preferences APIs,儘管這對圖書館來說可能是一個糟糕的選擇。

它們仍然在類路徑中嗎?

只有當你將該位置放在classpath上...並且這會使配置更加棘手。鑑於這些文件需要存儲在文件系統中,我建議使用FileInputStream或類似的文件。

+0

@ StephenC-I已經有我的文件。我想知道一種將這些文件打包到jar本身的方法,這樣使用jar的獨立應用程序就不必關心這些文件。爲了讓問題更清楚一些,我想確認一下,當這些文件是jar的一部分並被同一個jar中的類引用時,這個jar被其他幾個應用程序使用,引用是否相同因爲我們將訪問模塊中的普通資源文件?我的意思是,從應用程序的角度來看,classpath是否也有這些文件? –

0

使用Eclipse,我總是創建一個包'資源',在那裏放置jar需要的文件。我通過

this.getClass().getClassLoader().getResources("/resources/file.ext"); 

訪問文件(從幾乎任何地方)隨着導出 - >運行的JAR所有這些文件都包含在該.jar。我不確定這是否是正確的做法。另外,我對資源之前的「/」不是100%確定的,也許應該省略。

+3

OP提到了Eclipse嗎?他實際上正在討論將獨立於Eclipse安裝的應用程序/庫。 –

1

你有兩個選擇,第一個是將文件放在包結構中,這樣它們將被打包在jar中。

getClass().getResourceAsStream("/path/to/your/resource/resource.ext"); 

如果你想從一個名爲A,則類的靜態方法來調用它,你應該這樣寫:

A.class.getResourceAsStream("/path/to/your/resource/resource.ext"); 

的「/路徑」的一部分,你會從這樣的代碼讓他們的路徑是最頂層的包,而resource.ext是您的文件名。

另一種選擇是把他們的jar包之外,但隨後的罐子需要知道自己的位置:

  • 將它作爲參數傳遞給程序(Java的罐子program.jar系統/路徑/到/文件)
  • 硬編碼從中,你會讀與路徑

我undestood你queastion並回答它的方式文件的位置,它無關classpath

CLASSPATH變量是一種告訴應用程序(包括JDK工具)在哪裏查找用戶類的方法。 (類屬於JRE,JDK平臺的一部分,並擴展應該通過其他方式來定義,比如引導類路徑或擴展目錄。)

編輯: ,但你仍然可以,把它放在那裏並從這樣的代碼得到它:

System.getProperty("java.class.path"); 

然而它會需要一些邏輯來解析它。