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

发布于 2024-11-03 02:37:48 字数 172 浏览 4 评论 0原文

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

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

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

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

I there a way in the java.io package to convert a relative path containing "../" to an absolute path?

My goal is to remove the "../" part of the path because

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

Does not seem to support ../ in file path under windows

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

烂人 2024-11-10 02:37:48

--- 在评论 ../ 仍在路径中时进行编辑 ---

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();

将在不折叠(跟随)相对路径链接的情况下执行此操作。

--- Edited when comment was made that the ../ was still in the path ---

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());
    }

}

will run with the output

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

based on my current working directory of /home/ebuck/workspace/State

Note that you asked for the complete real file path, which technically an absolute path is a complete, real file path, it's just not the shortest complete real file path. So, if you want to do it fast and dirty, one can just add "../../home" to the current working directory and obtain a full, complete file path (albeit a wordy one that contains unnecessary information).

If you want the shortest full, complete file path, that's what getCanonicalPath() is used for. It throws an exception; because, some joker out there will probably ask for "../../home" when in the root directory.

--- Original post follows, with edits ---

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

Will do so collapsing (following) the relative path links (. and ..).

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

Will do so without collapsing (following) the relative path links.

灰色世界里的红玫瑰 2024-11-10 02:37:48
String path = new File("../../dir/file.ext").getCanonicalPath();
String path = new File("../../dir/file.ext").getCanonicalPath();
森林散布 2024-11-10 02:37:48
File f = new File("..");
String path = f.getAbsolutePath();
File f = new File("..");
String path = f.getAbsolutePath();
影子是时光的心 2024-11-10 02:37:48

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

Sometimes File.getCanonicalPath() may not be desired since it may resolve things like symlinks, so if you want to maintain the "logical" path that File.getAbsolutePath() provides, you cannot use getCanonicalPath(). Also, IIRC, gCP() can thrown an exception while gAP() does not, and gAP() can refer to a path does not exist.

I've encounter the '..' problem a long time ago. Here is a utility method I wrote to remove the '..'s in a path:

  /**
   * 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)");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文