2014-01-11 27 views
31

我想了解Java在創建File對象時解析相對路徑的方式。Java如何在新File()中解析相對路徑?

OS使用:視窗

對於下面的代碼片段,我得到了IOException,因爲它無法找到路徑:

@Test 
public void testPathConversion() { 
     File f = new File("test/test.txt"); 
     try { 
      f.createNewFile(); 
      System.out.println(f.getPath()); 
      System.out.println(f.getAbsolutePath());  
      System.out.println(f.getCanonicalPath()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
} 

我的理解這裏,爪哇將其視爲絕對回報提供的路徑路徑不存在時發生錯誤。所以這是有道理的。

當我更新了上面的代碼中使用相對路徑:

@Test 
    public void testPathConversion() { 
     File f = new File("test/../test.txt"); 
     try { 
      f.createNewFile(); 
      System.out.println(f.getPath()); 
      System.out.println(f.getAbsolutePath());  
      System.out.println(f.getCanonicalPath()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     }  
    } 

它創建一個新的文件,並提供以下的輸出:

test\..\test.txt 
C:\JavaForTesters\test\..\test.txt 
C:\JavaForTesters\test.txt 

在這種情況下,我的假設是,即使所提供的路徑不存在,因爲路徑包含「/../」,java會將其視爲相對路徑並在user.dir中創建該文件。所以這也是有道理的。

但如果我更新下面的相對路徑:

@Test 
    public void testPathConversion() { 
     File f = new File("test/../../test.txt"); 
     try { 
      f.createNewFile(); 
      System.out.println(f.getPath()); 
      System.out.println(f.getAbsolutePath()); 
      System.out.println(f.getCanonicalPath()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

然後我得到IOException異常:訪問被拒絕。

我的問題是:

  1. 爲什麼"test/../test.txt"被視爲相對路徑和"user.dir"創建文件,但"test/../../test.txt"返回一個錯誤?它在哪裏嘗試爲路徑"test/../../test.txt"創建文件?
  2. 當找不到指定的相對路徑時,該文件似乎在user.dir中創建。所以,在我看來,以下兩種情況做同樣的事情:

    //scenario 1 
    File f = new File("test/../test.txt"); 
    f.createNewFile(); 
    
    //scenario 2 
    File f = new File("test.txt"); 
    f.createNewFile(); 
    

那麼,有沒有一個真正的世界的案例,其中一個會用,而不是場景2場景1?

我想我錯過了一些很明顯的東西,或者從根本上誤解了相對路徑。我瀏覽了File的Java文檔,但無法找到解釋。關於相對路徑,在Stack Overflow中發佈了相當多的問題,但是我查找的是針對特定場景的,而不是關於如何解析相對路徑。

如果有人能解釋我這是如何工作的或指向一些相關鏈接,這將是非常好的嗎?

+0

請注意,'user.dir'是一個很不穩定的地方,它應該依賴於脆弱。另一個需要考慮的因素是應用程序。可能沒有安裝在它有*寫權限的地方。**將文件放在'user.home'(的子目錄)中會更加優化和健壯。請參閱[這個答案](http://stackoverflow.com/a/10166623/418556)一個簡短的例子。 –

+0

注意:'test/test.txt'和'test /../ test.txt'都是相對路徑。這個意義上的相對與嵌入式「..」組件的存在無關。 – Boann

回答

17

有一個working directory的概念。
此目錄由.(點)表示。
在相對路徑中,其他所有內容都與其相關。

簡單地說,.(工作目錄)就是運行程序的地方。
在某些情況下,工作目錄可以更改,但通常這是
點代表的是什麼。我認爲你的情況是C:\JavaForTesters\

所以test\..\test.txt表示:子目錄在我的工作目錄test
,然後一個級別,那麼
文件test.txt。這與test.txt基本相同。

欲瞭解更多詳情請點擊這裏。

http://docs.oracle.com/javase/7/docs/api/java/io/File.html

http://docs.oracle.com/javase/tutorial/essential/io/pathOps.html

5

工作目錄是一個共同的理念在幾乎所有的操作系​​統和程序語言等,這是在程序運行的目錄。這通常是(但並不總是,有辦法改變它)應用程序所在的目錄。

相對路徑是指沒有驅動器說明符的路徑。因此,在linux中,它們不是以/開頭的,它們並不以C:\等開頭,它們始終從您的工作目錄開始。

絕對路徑是以驅動器(或網絡路徑的機器)說明符開頭的路徑。他們總是從開車的那一刻開始。

7

當您的路徑在Unix中或在java資源路徑中的根目錄開頭,即C:\/時,它被認爲是絕對路徑。其他一切都是相對的,所以

new File("test.txt") is the same as new File("./test.txt") 

new File("test/../test.txt") is the same as new File("./test/../test.txt") 

getAbsolutePathgetCanonicalPath之間的主要區別是,第一個串接一個父和子路徑,因此它可能包含黑點:...getCanonicalPath將始終返回特定文件的相同路徑。

注:File.equals使用路徑(getAbsolutePath)比較文件的抽象形式,所以這意味着,對於相同的兩個File對象可能不等於和File s爲不安全的收藏使用像MapSet

0

在Windows和Netbeans的可以設置相對路徑:如果你有內部Source Packages 代碼

new FileReader("src/PACKAGE_NAME/FILENAME"); 

new FileReader("src\\PACKAGE_NAME\\FILENAME"); 

在Linux和Netbeans,你可以設置爲相對路徑我不知道是否它是相同的日食或其他IDE

0

只有略有關係的問題,但試圖包裝你的頭阿魯找到這個。如此不直觀:

import java.nio.file.*; 
class Main { 
    public static void main(String[] args) { 
    Path p1 = Paths.get("/personal/./photos/./readme.txt"); 
    Path p2 = Paths.get("/personal/index.html"); 
    Path p3 = p1.relativize(p2); 
    System.out.println(p3); //prints ../../../../index.html !! 
    } 
}