filepath 文件路径处理

Go语言提供了filepath模块用于处理文件路径字符串,对于文件路径的处理,我们应该使用filepath而非自己手动切割和拼接字符串。filepath有更好的跨平台兼容性,相比我们自己实现代码也更加健壮。

跨平台路径分隔符

我们知道Windows和Linux的文件系统路径分隔符是不同的,如果混用可能导致一些错误。Go语言提供了os.PathSeparator作为跨平台的路径分隔符。我们对文件路径字符串进行处理时,应该使用该值,而非直接使用正斜杠或反斜杠。

package main

import (
    "fmt"
    "os"
)

func main() {
    s := os.PathSeparator
    fmt.Println(string(s))
}

这里os.PathSeparator实际上是一个rune类型(即int32),这里我们将其转换为了string类型进行输出。在Windows下,上面代码会输出反斜杠\

获取文件路径和文件名

Dir()方法会解析一个文件路径字符串,返回其所在的目录;Base()方法则会返回文件名。

package main

import (
    "fmt"
    "path/filepath"
)

func main() {
    dir := filepath.Dir("D:\\workspace-go\\filedemo\\data.txt")
    base := filepath.Base("D:\\workspace-go\\filedemo\\data.txt")

    fmt.Println(dir)
    fmt.Println(base)
}

运行结果:

D:\workspace-go\filedemo
data.txt

如果指定路径最后带有路径分隔符,它会被视为文件夹进行处理。Dir()Base()对文件的路径和文件夹的路径处理不同,举例来说,如果上面字符串s的值为D:\\workspace-go\\filedemo\\,输出结果为:

D:\workspace-go\filedemo
filedemo

计算绝对路径

IsAbs()方法用于判断一个路径是否为绝对路径,其内部逻辑很简单,/开头的路径就是Linux下的绝对路径,盘符开头的路径如c:/就是Windows下的绝对路径。Abs()方法用于计算一个路径的绝对路径,注意这个方法是根据当前Go程序的工作目录来计算的。

package main

import (
    "fmt"
    "path/filepath"
)

func main() {
    s := "data.txt"
    // 判断是否为绝对路径
    result := filepath.IsAbs(s)
    fmt.Printf("路径是否为绝对路径 %v\n", result)

    // 获取一个路径的绝对路径
    absPath, err := filepath.Abs(s)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("绝对路径 %v\n", absPath)
}

运行结果:

路径是否为绝对路径 false
绝对路径 D:\workspace-go\filedemo\data.txt

注:这里我的程序所在目录为D:\workspace-go\filedemo\

计算相对路径

Rel()方法用于计算一个路径相对于另一个路径的相对路径值,其计算结果可能带有目录回退符..,这么说可能有点难理解,我们直接看一个例子。

package main

import (
    "fmt"
    "path/filepath"
)

func main() {
    s1, err := filepath.Rel("E:\\", "E:\\workspace\\data.txt")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(s1)

    s2, err := filepath.Rel("E:\\demo", "E:\\workspace\\data.txt")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(s2)
}

运行结果:

workspace\data.txt
..\workspace\data.txt

路径切分

Split()方法用于处理路径切分,其返回值是dirfile,对应文件所在路径值和文件名。

package main

import (
    "fmt"
    "path/filepath"
)

func main() {
    var dir, file string
    dir, file = filepath.Split("E:\\workspace-go\\data.txt")
    fmt.Printf("dir [%v] file[%v]\n", dir, file)

    dir, file = filepath.Split("data.txt")
    fmt.Printf("dir [%v] file[%v]\n", dir, file)

    dir, file = filepath.Split("E:\\workspace-go\\")
    fmt.Printf("dir [%v] file[%v]\n", dir, file)
}

运行输出:

dir [E:\workspace-go\] file[data.txt]
dir [] file[data.txt]
dir [E:\workspace-go\] file[]

注意:和Dir()Base()方法类似,Split()方法对文件夹和文件的处理是有区别的,而判断目录或是文件的依据是字符串结尾的分隔符。

路径拼接

Join()方法用于拼接路径,下面是一个例子。

package main

import (
    "fmt"
    "path/filepath"
)

func main() {
    s := filepath.Join("E:\\", "workspace-go", "data.txt")
    fmt.Println(s)
}

运行结果:

E:\workspace-go\data.txt

遍历目录

Walk()方法能够以递归形式遍历目录下的所有文件和文件夹。

package main

import (
    "fmt"
    "io/fs"
    "path/filepath"
)

func main() {
    if err := filepath.Walk("E:\\", func(path string, info fs.FileInfo, err error) error {
        fmt.Println(path)
        return err
    }); err != nil {
        fmt.Println(err)
        return
    }
}

运行上面代码后,会输出整个E盘下的所有文件和文件夹信息。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。