【问题标题】:Resolving symlinks and ".." together in one path在一条路径中同时解析符号链接和“..”
【发布时间】:2013-02-20 10:41:09
【问题描述】:

这就是问题所在。我有一个指向其他目录的符号链接:

$ls -l /foo/bar
lrwxrwxrwx  /foo/bar  ->  /target/bar

foo目录下有一个文件x

$ls -l /foo
lrwxrwxrwx   me me  314   x

现在,我想通过以下路径访问x /foo/bar/../x

$ls -l /foo/bar/../x : No such file or directory

这在 Bash 中不起作用,但是有什么方法可以使用 File api 使其在 Java 中起作用?目录结构可以是任意的,因此可能会出现/foo/bar/1/2/3/4/5/../../../../../../x 等情况。

换句话说,我正在寻找检查文件是否存在的magic() 方法的内容(假设前面提到的目录结构):

magic("/foo/x") ... true
magic("/foo/bar/../x") ... true
magic("/foo/bar/1//../../x") ... true
magic("/foo/bar/1/2/3/4/5/../../../../../../x") ... true
magic("/foo/bar//1/../2/../../x") ... true
magic("/foo/bar/1/2/../3/../../../x") ... true
magic("/foo/bar/1/2/./../3/../4//../../../x") ... true

magic("/foo/bar/x") ... false
magic("/foo/bar/1/../x") ... false
magic("/foo/bar/1/2/3/4/../../../../../../x") ... false
magic("/foo/bar//1/../2/../x") ... false

注意 1: getCanonicalPath() 对我不起作用,因为它首先解析符号链接,然后解析所有 "..""。 " 在路径中。我需要反之亦然。

注意 2:路径中可能还有其他符号链接,它应该以相同的方式工作(dir 2 可能是符号链接)。

注意 3:x 文件位于 /foo 中。

到目前为止,我似乎需要一个上下文无关语法的解析器,这个问题没有更简单的解决方案吗?

【问题讨论】:

  • 这是 Linux 如何解析路径的工件。这不是 Bash 或 Java 做的。
  • 你想做什么?如果您想做的事情是可能的,那么访问文件系统路径将是完全模棱两可的。
  • @Falmarri:我只需要它 :) 很难用全图来解释,这就是为什么我在这里只提取问题的本质。
  • @OliCharlesworth 我知道,我需要它按照我所描述的方式行事。它是进行一些配置的模块的一部分。
  • @JiriKremser:好的。好吧,您不太可能找到预先准备好的解决方案,因为这不是一件正常的事情。如果您真的需要这样做,那么标记和计算“..”的出现次数听起来并不是世界上最难的事情......

标签: java linux file file-io symlink


【解决方案1】:

如果我理解正确,Path.normalize() 方法应该完全符合您的要求?

它消除了..(除其他外),它的文档说

此方法不访问文件系统;该路径可能找不到存在的文件。从路径中删除“..”和前面的名称可能会导致该路径定位到与原始路径不同的文件。当前面的名称是符号链接时,可能会出现这种情况。

您不需要解析路径上的其他符号链接,当您最终尝试访问该文件时,操作系统会解析它们。如果您仍然想解析符号链接,请在之后调用 Path.toRealPath()NOFOLLOW_LINKS 作为参数)。

【讨论】:

  • +1 哇,我上面的评论是错误的;这样的方法确实存在!这在什么情况下会有用?
  • @OliCharlesworth 我不知道,但这似乎很常见。 Python 有一个等效函数(os.path.normpath():docs.python.org/2/library/os.path.html#os.path.normpath)。
  • 可能 API 设计者添加了这样一个方法,因为它比较简单,不需要文件系统(因此没有 IOExceptions 和磁盘访问慢),并且不依赖于平台。
  • 它可以用于您有一个不需要映射到文件系统的路径的地方。在处理 URL 时非常有用。
【解决方案2】:

Path 是一个 Java7 API。如果您坚持使用 Java6,我认为以下内容也适合您:http://commons.apache.org/proper/commons-io/javadocs/api-1.4/org/apache/commons/io/FilenameUtils.html#normalize%28java.lang.String%29

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-17
    • 2016-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-23
    相关资源
    最近更新 更多