[英]Exported JAR unable to read local file
我的Java應用程序在名為“ assets”的頂級文件夾中有一個名為“ classes”(簡單的List<String>
)的本地文件。 當我從Eclipse運行以下代碼時,讀取文件沒有問題。
try { // read in classes from local file
ObjectInputStream inputStream =
new ObjectInputStream(new FileInputStream("assets\\classes".replace("\\", "/")));
listOfClasses = (List<String>) inputStream.readObject();
System.out.println("*** Reading local copy of classes file ***");
inputStream.close();
} catch (FileNotFoundException e) { e.printStackTrace();
} catch (ClassNotFoundException e) { e.printStackTrace();
} catch (IOException e) { e.printStackTrace(); }
當我將應用程序導出為JAR並在另一台計算機上運行時,在第三行顯示java.io.FileNotFoundException
。 我將“ assets”文件夾添加到了構建路徑,因此它應該在JAR中。
有人知道這是怎么回事嗎?
FileOutputStream
只是打開一個本地文件。 它應該是絕對的( /home/user/...
或c:\\temp\\...
)或相對於當前目錄。 例如,在Windows上,默認情況下就是包含JAR的目錄。
如果打算將classes
文件打包到 JAR中,則應使用getResourceAsStream
,如@guleryuz所述。 路徑應該是從CLASSPATH根目錄(即JAR文件的根目錄)開始的絕對路徑,例如"/assets/classes"
,或者相對於調用類的包而言是(更好)。
說到類,我強烈建議不要使用getClass()
因為它是一種多態方法。 有兩種獲取類的方法:通過在對象上調用getClass()
或通過訪問靜態class
“字段”。 如果您有一個名為myObject
的MyClass
實例,則myObject.getClass()
和MyClass.class
本質上是同一件事。 但! 如果你的類是由類從另一個包覆蓋,也就是說, TheirClass
,那么,對於實例TheirClass
, getClass()
將返回TheirClass.class
,即使您呼叫getClass()
從你的代碼。 因此,除非將您的類聲明為final
,否則使用getClass().getResource...
始終是個壞主意getClass().getResource...
因為您永遠不知道何時有人重寫您的類。 而且您不應該知道甚至不在乎!
假設所有這些,在名為my.package
的包中就有一個名為MyClass
的類。 JAR可以具有以下結構:
my/
package/
MyClass.class
assets/
classes
然后,調用MyClass.class.getResourceAsStream("assets/classes")
應該可以解決問題。 另外,也可以是MyClass.class.getResourceAsStream("/my/package/assets/classes")
。 請注意,絕對路徑並非從項目目錄開始,您可能在其中有src
或src/main
或您的構建系統使用的任何目錄。 它是相對於CLASSPATH根目錄的(是的, 絕對路徑是相對於CLASSPATH根目錄的,即使這聽起來很混亂)。 也就是說,它從您的軟件包所在的目錄開始。
最后但並非最不重要的一點是,如果您使用類似Maven的構建系統(例如,Maven或Gradle),則Java源代碼將轉到src/main/java
,而資源文件(如您的文件)將轉到src/main/resources
。 它們最終位於您的JAR文件中的完全相同的位置。 也就是說, src/main/java/package/MyClass.java
被編譯為package/MyClass.class
,而src/main/resources/package/assets/classes
進入package/assets/classes
。 但是,為了使構建系統確定如何處理文件,必須將它們放置在正確的目錄中: *.java
轉到java
,資源轉到resources
。
因此,假設類似Maven的約定,則項目結構應為
src/
main/
java/
my/
package/
MyClass.java
src/
main/
resources/
my/
package/
assets/
classes
有了這樣的結構,您將獲得具有上述結構的JAR文件。 看起來有點瘋狂,但是一旦掌握了它,它就會非常有用。
如果您不使用類似Maven的構建系統,那么我不知道如何配置Eclipse。 不同的IDE可能有各自的約定,並且我一直將Maven與Eclipse結合使用。 例如,某些IDE喜歡將Java源和資源放入同一目錄樹中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.