2011-04-22 69 views
1

我有一種方法在java.io包中將包含「../」的相對路徑轉換爲絕對路徑嗎?如何在java中獲得「../../dir/file.ext」的完整真實文件路徑?

我的目標是去除路徑 「../」 的一部分,因爲

java.awt.Desktop.getDesktop().open() 

似乎不支持../文件路徑windows下

+0

可能重複[Java的解決相對路徑(http://stackoverflow.com/questions/5121967/java-resolve -relative-path) – Nix 2011-04-22 21:10:48

+1

很難想象現在任何文件路徑問題都不是重複的。 – 2011-04-22 21:27:27

回答

0
String path = new File("../../dir/file.ext").getCanonicalPath(); 
+0

我不認爲自己曾經「回覆」過第二位。 :-O – corsiKa 2011-04-22 21:08:43

+0

哈哈,我也注意到了:) – WhiteFang34 2011-04-22 21:09:04

+0

這不會取代改爲'getCanonicalPath文件路徑 – jumar 2011-04-22 21:10:50

0
File f = new File(".."); 
String path = f.getAbsolutePath(); 
1

---在發表評論時指出../仍在路徑中---

import java.io.File; 

public class Test { 

    public static void main(String[] args) throws Exception { 
     File file = new File("../../home"); 
     System.out.println(file.getCanonicalPath()); 
     System.out.println(file.getAbsolutePath()); 
    } 

} 

將與輸出

/home/ebuck/home 
/home/ebuck/workspace/State/../../home 

運行基於您要求的完整的真正的文件路徑,這在技術上是絕對路徑是一個完整的,真實的文件路徑/home/ebuck/workspace/State

注意我當前的工作目錄,它只是不是最短的完整真實文件路徑。所以,如果你想快速和骯髒地做到這一點,可以在當前的工作目錄中添加「../../home」,並獲得一個完整的完整文件路徑(儘管這是一個包含不必要信息的冗長的文件路徑)。

如果你想最短已滿,完整的文件路徑,這就是getCanonicalPath()用於什麼。它拋出一個異常;因爲,在那裏的一些小丑可能會要求在根目錄中的「../../home」。

---原帖如下,編輯---

new File("../../dir/file.ext").getCanonoicalPath(); 

將這樣做倒塌(以下)的相對路徑鏈接(...)。

new File("../../dir/file.ext").getAbsolutePath(); 

這樣做不會摺疊(跟隨)相對路徑鏈接。

+0

你想讓'getCanonicalPath()'實際從路徑中移除「../」。 'getAbsolutePath()'只是在那裏用「../」返回。 – pickypg 2011-04-22 21:12:23

0

有時File.getCanonicalPath()可能不是所希望的,因爲它可能會解析像符號鏈接這樣的東西,所以如果要維護File.getAbsolutePath()提供的「邏輯」路徑,則不能使用getCanonicalPath()。另外,IIRC,gCP()可以拋出異常,而gAP()不會拋出異常,並且gAP()可以引用不存在的路徑。

很久以前,我遇到了'..'問題。這是我寫的刪除實用方法「..的一個路徑:

/** 
    * Retrieve "clean" absolute path of a file. 
    * <p>This method retrieves the absolute pathname of file, 
    * with relative components (e.g. <tt>..</tt>) removed. 
    * Java's <tt>File.getAbsolutePath()</tt> does not remove 
    * relative components. For example, if given the pathname: 
    * </p> 
    * <pre> 
    * dir/subdir/subsubdir/../../file.txt 
    * </pre> 
    * <p>{@link File#getAbsolutePath()} will return something like: 
    * </p> 
    * <pre> 
    * /home/whomever/dir/subdir/subsubdir/../../file.txt 
    * </pre> 
    * <p>This method will return: 
    * </p> 
    * <pre> 
    * /home/whomever/dir/file.txt 
    * </pre> 
    * 
    * @param f  File to get clean absolute path of. 
    * @return Clean absolute pathname of <i>f</i>. 
    */ 
    public static String cleanAbsolutePath(
     File f 
) { 
    String abs = f.getAbsolutePath(); 
    if (!relDirPattern.matcher(abs).find()) { 
     // Nothing to do, so just return what Java provided 
     return abs; 
    } 
    String[] parts = abs.split(fileSepRex); 
    ArrayList<String> newPath = new ArrayList<String>(parts.length); 
    int capacity = 0; 
    for (String p : parts) { 
     if (p.equals(".")) continue; 
     if (p.equals("..")) { 
    if (newPath.size() == 0) continue; 
    String removed = newPath.remove(newPath.size() -1); 
    capacity -= removed.length(); 
    continue; 
     } 
     newPath.add(p); 
     capacity += p.length(); 
    } 

    int size = newPath.size(); 
    if (size == 0) { 
     return File.separator; 
    } 

    StringBuilder result = new StringBuilder(capacity); 
    int i = 0; 
    for (String p : newPath) { 
     ++i; 
     result.append(p); 
     if (i < size) { 
    result.append(File.separatorChar); 
     } 
    } 
    return result.toString(); 
    } 

    /** Regex string representing file name separator. */ 
    private static String fileSepRex  = "\\"+File.separator; 
    /** Pattern for checking if pathname has relative components. */ 
    private static Pattern relDirPattern = Pattern.compile(
     "(?:\\A|" + fileSepRex + ")\\.{1,2}(?:" + fileSepRex + "|\\z)"); 
相關問題