检查给定路径是否是golang中另一个的子目录

时间:2015-01-19 12:31:04

标签: go

假设我们有两条路径:

c:\foo\bar\bazc:\foo\bar

是否有任何包/方法可以帮助我确定一个是否是另一个的子目录?我正在寻找一个跨平台的选择。

4 个答案:

答案 0 :(得分:9)

您可以尝试使用path.filepath.Rel()

func Rel(basepath, targpath string) (string, error)
  

Rel返回一个相对路径,该路径在与targpath连接时带有插入分隔符,在词汇上等效于basepath
  也就是说,Join(basepath, Rel(basepath, targpath))相当于targpath本身

这意味着Rel("c:\foo\bar", "c:\foo\bar\baz")应为baz,这意味着c:\foo\bar\baz中完全包含子路径,并且没有任何“../”。
这同样适用于unix路径。

这会使c:\foo\bar\baz成为c:\foo\bar

的子目录

答案 1 :(得分:1)

我还没有找到适用于所有类型路径的可靠解决方案,但是最好的方法是按照VonC的建议使用filepath.Rel

如果两个文件路径都是绝对路径或相对路径(不允许混合),则可以使用,并且可以在Windows和Linux上使用:

func SubElem(parent, sub string) (bool, error) {
    up := ".." + string(os.PathSeparator)

    // path-comparisons using filepath.Abs don't work reliably according to docs (no unique representation).
    rel, err := filepath.Rel(parent, sub)
    if err != nil {
        return false, err
    }
    if !strings.HasPrefix(rel, up) && rel != ".." {
        return true, nil
    }
    return false, nil
}

以驱动器号开头的绝对Windows路径将需要进行额外检查。

答案 2 :(得分:0)

您可以使用函数path.filepath.Match()

  

匹配报告名称是否与外壳文件名称模式匹配。

例如:

pattern := "C:\foo\bar" + string(filepath.Separator) + "*"
matched, err := filepath.Match(pattern, "C:\foo\bar\baz")

matched应该为true的地方。

答案 3 :(得分:0)

试试这个代码。这将检查其中一个是否是另一个的子目录。尝试更改 base 和 path 的值,结果应该是有效的。

package main

import (
    "fmt"
    "path/filepath"
    "strings"
)

func main() {
    base := "/b/c/"
    path := "/a/b/c/d"

    if len(base) > len(path) {
        base, path = path, base
    }

    rel, err := filepath.Rel(base, path)
    fmt.Printf("Base %q: Path %q: Rel %q Err %v\n", base, path, rel, err)
    if err != nil {
        fmt.Println("PROCEED")
        return
    }

    if strings.Contains(rel, "..") {
        fmt.Println("PROCEED")
        return
    }

    fmt.Println("DENY")
}