2010-07-09 130 views
3

本主題中存在很多混淆。有人問了幾個問題。事情似乎還不清楚。 的ClassLoader,絕對文件路徑等等等等Java中項目文件夾的絕對路徑

假設我有一個項目的目錄結構,

 
MyProject-- 
      --dist   
      --lib 
      --src 
      --test 

我有一個資源說,在「LIB/TXT」目錄「txtfile.txt」。我想以系統獨立的方式訪問它。我需要項目的絕對路徑。 所以我可以代碼路徑作爲ABSPATH +「/ lib目錄/詞典/ txtfile.txt」

想我這樣做

java.io.File file = new java.io.File(""); //Dummy file 
    String abspath=file.getAbsolutePath(); 

我得到的當前工作目錄這不一定是項目的根。

想我從其中也包含「LIB/TXT/txtfile.txt」目錄結構和資源的「DIST」文件夾執行最終的「prj.jar」,它應該在這裏工作過。我應該絕對路徑的dist文件夾。

希望問題清楚。

+0

而且我覺得這種做法仍限於「UNIX」像目錄結構平臺,追加「/ lib目錄/字典/txtfile.txt「在Windows上將由於前向和反向差異而導致混亂! :| – 2010-07-09 04:49:11

+0

實際上,Java並不關心斜槓方向,儘管你只能明確指定非根驅動器,因爲'/'指向當前磁盤的根目錄。 – 2010-07-09 04:53:09

+0

System.getProperty(「file.separator」)將返回Windows環境的「\」和Unix(和類Unix)的返回值「/」。 – Catchwa 2010-07-09 04:57:41

回答

9

你確實應該使用getResource()getResourceAsStream()使用你的類加載器爲這樣的事情。特別是,這些方法使用您的ClassLoader來確定項目中資源的搜索上下文。

爲了拿起文本文件指定像getClass().getResource("lib/txtfile.txt")

爲了澄清:不是想着如何獲取資源的路徑,你應該要思考得到的資源 - 在這種情況下,在目錄中的文件的地方(也許是你的JAR內)。在這種情況下,不需要知道一些絕對路徑,只需要一些URL來獲取文件,ClassLoader就會爲您返回這個URL。如果你想打開一個文件流,你可以直接使用getResourceAsStream來實現這個功能。

你試圖通過類加載器訪問的資源需要在類路徑(在你的JAR文件的清單配置)。這很關鍵! ClassLoader使用Class-Path來查找資源,因此如果您在Class-Path中沒有提供足夠的上下文,它將無法找到任何內容。如果添加.,ClassLoader應根據引用資源的方式解決JAR內部或外部的任何問題,但您當然可以更具體。

引用以.爲前綴的資源將導致ClassLoader在JAR之外尋找文件,而不在資源路徑的前面添加句點將指示ClassLoader僅在JAR文件內查找。

這意味着,如果你有一些文件在目錄lib與名foo.txt的JAR,你想要得到的資源,那麼你會運行getResource("lib/foo.txt");

如果相同的資源是該JAR你」之外d運行getResource("./lib/foo.txt");

+0

馬克如我所說,我已經嘗試過它會上課裝載機。你能不能在我的情況下張貼一些關於如何解決它的片段? – 2010-07-09 04:57:22

+0

@MAK我瞭解這個事實,它必須由類加載器來處理。但是如何? java.net.URL url = getClass()。getResource(「lib/txtfile.txt」); 爲我返回一個空的URL! – 2010-07-09 05:03:14

+0

@Mark dist文件夾有一個prj.jar +「lib/txt/txtfile」資源。 (資源在jar外面運行) 我打算在最後tar dist文件夾來發布它 – 2010-07-09 05:12:53

0

@馬克是正確的。這是迄今爲止最簡單和最穩健的方法。

但是,如果你真的必須有一個File,那麼你最好的辦法是請嘗試以下操作:

  • 打開系統屬性「java.class.path」的內容轉換成路徑的列表,
  • 識別JAR路徑基於其文件名列表,
  • 弄清楚什麼是「../ ..」是相對於JAR路徑給你的‘工程’目錄,並
  • 構建目標路徑相對於項目目錄。

另一種替代方法是將項目目錄名稱嵌入到包裝腳本中,並使用-D選項將其設置爲系統屬性。也可以讓包裝腳本找出它自己的絕對路徑名;例如使用whence

2

首先,確保lib目錄在您的類路徑中。你可以在你的啓動腳本添加命令行參數做到這一點:

$JAVA_HOME/bin/java -classpath .:lib com.example.MyMainClass 

保存爲MyProject的/ start.sh或任何依賴於操作系統的腳本。

然後你就可以訪問TextFile.txt的(如正確地由Mark提到的)爲:

// if you want this as a File 
URL res = getClass().getClassLoader().getResource("text/textfile.txt"); 
File f = new File(res.getFile()); 

// As InputStream 
InputStream in = getClass().getClassLoader() 
     .getResourceAsStream("text/textfile.txt");