如何在java中获得“../../dir/file.ext”的完整真实文件路径?

问题描述:

我有一种方法在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

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

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

---在发表评论时指出../仍在路径中---

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

有时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)");