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

时间:2011-04-22 21:07:04

标签: java file relative-path

我在java.io包中有一种方法可以将包含“../”的相对路径转换为绝对路径吗?

我的目标是删除路径的“../”部分,因为

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

在Windows

下的文件路径中似乎不支持../

4 个答案:

答案 0 :(得分: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”添加到当前工作目录并获得完整,完整的文件路径(尽管是包含不必要信息的罗嗦文件路径)。 / p>

如果您希望最短完整,完整的文件路径,那就是getCanonicalPath()的用途。它引发了一个例外;因为,在根目录中,一些小丑可能会要求“../../home”。

---原帖如下,编辑---

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

这样做会折叠(跟随)相对路径链接(...)。

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

不会折叠(跟随)相对路径链接。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

答案 3 :(得分: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)");