【问题标题】:How to get the complete real file path for "../../dir/file.ext" in java?如何在java中获取“../../dir/file.ext”的完整真实文件路径?
【发布时间】:2011-04-22 21:07:03
【问题描述】:

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

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

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

windows下文件路径好像不支持../

【问题讨论】:

标签: java file relative-path


【解决方案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();

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

【讨论】:

  • 您希望getCanonicalPath() 从路径中实际删除“../”。 getAbsolutePath() 只需在其中返回“../”即可。
【解决方案2】:
String path = new File("../../dir/file.ext").getCanonicalPath();

【讨论】:

  • 我认为我以前从未在回复中“绑定”到第二个。 :-O
  • 这不会替换文件路径的 ../ 部分
  • 根据需要更改为getCanonicalPath()。看来.. 可以保留,否则。
  • @WhiteFang32,你是 100% 的。绝对路径仅返回该路径(以及绝对路径,无论多么复杂),而规范尝试返回最短(最佳)路径。
【解决方案3】:
File f = new File("..");
String path = f.getAbsolutePath();

【讨论】:

    【解决方案4】:

    有时可能不需要 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)");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-16
      • 2020-01-29
      • 1970-01-01
      • 2018-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多