首页 > 其他分享 >go文件夹遍历

go文件夹遍历

时间:2023-05-17 14:47:57浏览次数:45  
标签:files 遍历 err filepath fmt Println 文件夹 go path

path/filepath 包涉及到路径操作时,路径分隔符使用 os.PathSeparator. Go是一个跨平台的语言,不同系统,路径表示方式有所不同,比如 Unix 和 Windows 差别很大.本包能够处理所有的文件路径,不管是什么系统.

Go标准库中还有path, path 和 path/filepath 函数有点重复,大部分情况下建议使用 path/filepath.

1.示例代码:package path

package main;
 
import (
    "fmt"
    "path"
)
 
//go语言path包的学习
 
func main() {
    //返回路径的最后一个元素
    fmt.Println(path.Base("./github.com/mojocn/c"));
    //如果路径为空字符串,返回.
    fmt.Println(path.Base(""));
    //如果路径只有斜线,返回/
    fmt.Println(path.Base("///"));
 
    //返回等价的最短路径
    //1.用一个斜线替换多个斜线
    //2.清除当前路径.
    //3.清除内部的..和他前面的元素
    //4.以/..开头的,变成/
    fmt.Println(path.Clean("./github.com/mojocn/../"));
 
    //返回路径最后一个元素的目录
    //路径为空则返回.
    fmt.Println(path.Dir("./github.com/mojocn/c"));
 
    //返回路径中的扩展名
    //如果没有点,返回空
    fmt.Println(path.Ext("./github.com/mojocn/c/d.jpg"));
 
    //判断路径是不是绝对路径
    fmt.Println(path.IsAbs("./github.com/mojocn/c"));
    fmt.Println(path.IsAbs("/github.com/mojocn/c"));
 
    //连接路径,返回已经clean过的路径
    fmt.Println(path.Join("./a", "b/c", "../d/"));
 
    //匹配文件名,完全匹配则返回true
    fmt.Println(path.Match("*", "a"));
    fmt.Println(path.Match("*", "a/b/c"));
    fmt.Println(path.Match("\\b", "b"));
 
    //分割路径中的目录与文件
    fmt.Println(path.Split("./github.com/mojocn/c/d.jpg"));
}

2.示例代码:package path/filepath

filepath.Join("C:/a", "/b", "/c") 拼接目录

package main;
 
import (
    "path/filepath"
    "fmt"
    "os"
)
 
//学习filepath包,兼容各操作系统的文件路径
 
func main() {
    //返回所给路径的绝对路径
    path, _ := filepath.Abs("./1.txt");
    fmt.Println(path);
 
    //返回路径最后一个元素
    fmt.Println(filepath.Base("./1.txt"));
    //如果路径为空字符串,返回.
    fmt.Println(filepath.Base(""));
    //如果路径只有斜线,返回/
    fmt.Println(filepath.Base("///"));
 
    //返回等价的最短路径
    //1.用一个斜线替换多个斜线
    //2.清除当前路径.
    //3.清除内部的..和他前面的元素
    //4.以/..开头的,变成/
    fmt.Println(filepath.Clean("C:/github.com/mojocn/../c"));
    fmt.Println(filepath.Clean("./1.txt"));
 
    //返回路径最后一个元素的目录
    //路径为空则返回.
    fmt.Println(filepath.Dir("./github.com/mojocn/c"));
    fmt.Println(filepath.Dir("C:/github.com/mojocn/c"));
 
    //返回链接文件的实际路径
    path2, _ := filepath.EvalSymlinks("1.lnk");
    fmt.Println(path2);
 
    //返回路径中的扩展名
    //如果没有点,返回空
    fmt.Println(filepath.Ext("./github.com/mojocn/c/d.jpg"));
 
    //将路径中的/替换为路径分隔符
    fmt.Println(filepath.FromSlash("./github.com/mojocn/c"));
 
    //返回所有匹配的文件
    match, _ := filepath.Glob("./*.go");
    fmt.Println(match);
 
    //判断路径是不是绝对路径
    fmt.Println(filepath.IsAbs("./github.com/mojocn/c"));
    fmt.Println(filepath.IsAbs("C:/github.com/mojocn/c"));
 
    //连接路径,返回已经clean过的路径
    fmt.Println(filepath.Join("C:/a", "/b", "/c"));
 
    //匹配文件名,完全匹配则返回true
    fmt.Println(filepath.Match("*", "a"));
    fmt.Println(filepath.Match("*", "C:/github.com/mojocn/c"));
    fmt.Println(filepath.Match("\\b", "b"));
 
    //返回以basepath为基准的相对路径
    path3, _ := filepath.Rel("C:/github.com/mojocn", "C:/github.com/mojocn/c/d/../e");
    fmt.Println(path3);
 
    //将路径使用路径列表分隔符分开,见os.PathListSeparator
    //linux下默认为:,windows下为;
    fmt.Println(filepath.SplitList("C:/windows;C:/windows/system"));
 
    //分割路径中的目录与文件
    dir, file := filepath.Split("C:/github.com/mojocn/c/d.jpg");
    fmt.Println(dir, file);
 
    //将路径分隔符使用/替换
    fmt.Println(filepath.ToSlash("C:/github.com/mojocn"));
 
    //返回分区名
    fmt.Println(filepath.VolumeName("C:/github.com/mojocn/c"));
 
    //遍历指定目录下所有文件
    filepath.Walk("./", func(path string, info os.FileInfo, err error) error {
        fmt.Println(path)
        return nil
    })
}

3. 文件夹遍历

Go 语言中进行目录遍历的原生方法主要是以下3种:

  • filepath.Walk()
  • ioutil.ReadDir()
  • os.File.Readdir()

性能是越底层越高(上层其实是对底层API的封装).

3.1 filepath.Walk()

遍历根目录(root)下的文件树,为树中的每个文件或目录(包括根目录)调用walkFn.所有在访问文件和目录时出现的错误都由walkFn过滤. 遍历按词法顺序进行,这使得输出是确定的,但对于非常大的目录来说,遍历可能是低效的. filepath.Walk()不会跟进符号链接.

package main
 
import (
    "flag"
    "fmt"
    "os"
    "path/filepath"
)
 
const (
    layout = "2006-01-02 15:04:05"
)
 
func VisitFile(fp string, fi os.FileInfo, err error) error {
    if err != nil {
        fmt.Println(err) // can't walk here,
        return nil       // but continue walking elsewhere
    }
    if fi.IsDir() {
        return nil // not a file.  ignore.
    }
    // 过滤输出内容
    matched, err := filepath.Match("*.txt", fi.Name())
    if err != nil {
        fmt.Println(err) // malformed pattern
        return err       // this is fatal.
    }
    if matched {
        // fmt.Println(fp)
        fmt.Printf("Name: %s, ModifyTime: %s, Size: %v\n", fp, fi.ModTime().Format(layout), fi.Size())
    }
    return nil
}
 
func main() {
    var path = flag.String("path", ".", "The path to traverse.")
    flag.Parse()
 
    filepath.Walk(*path, VisitFile)
}

3.2 ioutil.ReadDir

filepath.Walk()会自动遍历子目录,但有些时候我们不希望这样,如果只想看当前目录, 或手动指定某几级目录中的文件,这个时候,可以使用 ioutil.ReadDir 进行替代.

package main
 
import (
    "flag"
    "fmt"
    "io/ioutil"
    "log"
)
 
func main() {
    var path = flag.String("path", ".", "The path to traverse.")
    flag.Parse()
 
    files, err := ioutil.ReadDir(*path)
    if err != nil {
        log.Fatal(err)
    }
 
    for _, file := range files {
        fmt.Println(file.Name())
    }
}

3.3 os.File.os.File.Readdir

package main
 
import (
    "fmt"
    "io/ioutil"
    "os"
    "path/filepath"
)
 
// https://stackoverflow.com/questions/14668850/list-directory-in-go/49196644#49196644
 
func main() {
    var (
        root  string
        err   error
    )
 
    // root = "/home/manigandan/Desktop/Manigandan/sample"
    root = "."
      f, err := os.Open(root)
      if err != nil {
          return files, err
      }
      fileInfo, err := f.Readdir(-1)
      f.Close()
      if err != nil {
          return files, err
      }
   
      for _, file := range fileInfo {
          fmt.Println(file.Name())
      }
}

3.4 方法封装的一个演示和对比

package main
 
import (
    "fmt"
    "io/ioutil"
    "os"
    "path/filepath"
)
 
// https://stackoverflow.com/questions/14668850/list-directory-in-go/49196644#49196644
 
func main() {
    var (
        root  string
        files []string
        err   error
    )
 
    // root = "/home/manigandan/Desktop/Manigandan/sample"
    root = "."
    // filepath.Walk
    files, err = FilePathWalkDir(root)
    if err != nil {
        panic(err)
    }
    // ioutil.ReadDir
    files, err = IOReadDir(root)
    if err != nil {
        panic(err)
    }
    //os.File.Readdir
    files, err = OSReadDir(root)
    if err != nil {
        panic(err)
    }
 
    for _, file := range files {
        fmt.Println(file)
    }
}
 
func FilePathWalkDir(root string) ([]string, error) {
    var files []string
    err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
        if !info.IsDir() {
            files = append(files, path)
        }
        return nil
    })
    return files, err
}
 
func IOReadDir(root string) ([]string, error) {
    var files []string
    fileInfo, err := ioutil.ReadDir(root)
    if err != nil {
        return files, err
    }
 
    for _, file := range fileInfo {
        files = append(files, file.Name())
    }
    return files, nil
}
 
func OSReadDir(root string) ([]string, error) {
    var files []string
    f, err := os.Open(root)
    if err != nil {
        return files, err
    }
    fileInfo, err := f.Readdir(-1)
    f.Close()
    if err != nil {
        return files, err
    }
 
    for _, file := range fileInfo {
        files = append(files, file.Name())
    }
    return files, nil
}

The End

线上交流工具: 在你的terminal中输入 ssh $用户@mojotv.cn

在你的terminal中输入 ssh mojotv.cn hn 查看最新 hacknews

标签:files,遍历,err,filepath,fmt,Println,文件夹,go,path
From: https://www.cnblogs.com/cheyunhua/p/17408659.html

相关文章

  • SRE Google 运维解密读书笔记一:SRE 方法论概述
    SREGoogle运维解密,是SRE领域的启蒙之作,讲述了Google的SRE实践,SRE就是从Google流传出来的。本文是读书笔记,第一篇,概述SRE方法论。帮大家把书读薄,当然,也加入了一些我的个人理解,希望对你有帮助。为何需要SRE传统的sysadmin的方式,偏手工运维,机器越多所需运维工程......
  • 成品直播源码,golang计算时间段内的工作日数量
    成品直播源码,golang计算时间段内的工作日数量 packagemainimport("fmt""time")funcmain(){start,_:=time.Parse("2006-01-02","2021-10-01")end,_:=time.Parse("2006-01-02","2021-10-31")total,days:=CalcWorkH......
  • 如何使用Go与MQTT进行通信
    简介本文介绍了如何使用Go编程语言与MQTT(MessageQueuingTelemetryTransport)进行通信。MQTT是一种轻量级的消息传输协议,广泛应用于物联网和实时通信场景。通过本文的指导,您将学习如何使用Go语言创建MQTT客户端,进行消息的发布和订阅。准备工作在开始之前,请确保您已完......
  • Django authenticate() 函数查找不到与提交的用户名和密码匹配的用户,则会返回 None。
    在你的userAPP下面添加一个utils.py文件classUsernameMobileBackend(ModelBackend):defauthenticate(self,request,username=None,password=None,**kwargs):"""重写人做方法"""#使用账号查询运河#如果用户名查询到用......
  • Golang基础-字节跳动青训营
    Golang安装访问https://go.dev/,点击Download,下载对应平台安装包,安装即可如果无法访问上述网址,可以改为访问https://studygolang.com/dl下载安装如果访问github速度比较慢,建议配置gomodproxy,参考https://goproxy.cn/里面的描述配置,下载第三方依赖包的速度可以大......
  • googlebenchmark
    pref原理及效率计算:top--PR/NI(priority/nice)/proc/stat其他fs文件信息.gbenchmark配置及使用:安装方式(注:***RPP使用cmake方式):cmake方式:设计框架:othertools.pref原理及效率计算:linux官方参考blog参考top--PR/NI(priority/nice)priority是比较好理解的......
  • mongo笔记
    #登录mongo数据库mongomongo-u用户名-p密码--authenticationDatabase数据库名#数据库简单操作showdbsuse数据库名showtablesdb.数据库名.find()db.createCollection("集合名")db.集合名.drop()#导出导入操作mongoexport-d数据库名-c集合名-o/db/Si......
  • Map的遍历方式
    Map是一种键值对的数据结构,Java中提供了多种遍历Map的方式,包括以下几种:使用for-each循环遍历Map的键或值Map<String,Integer>map=newHashMap<>();//添加键值对map.put("A",1);map.put("B",2);map.put("C",3);//遍历键for(Stringkey:map.keySet()){......
  • Map的遍历方式
    Map是一种键值对的数据结构,Java中提供了多种遍历Map的方式,包括以下几种:使用for-each循环遍历Map的键或值Map<String,Integer>map=newHashMap<>();//添加键值对map.put("A",1);map.put("B",2);map.put("C",3);//遍历键for(Stringkey:map.keySet()){......
  • An Attempt at Reducing Costs of Disk I/O in Go
    为了实现磁盘上的IO,go语言使用一组IO线程池用来提高CPU的使用率本文是在go语言上尝试了接入了linuxlibaio,并没有发现性能的提升。使用O_DIRECT意味着数据直接到达磁盘上,这将不能有效的利用pagecache用来加速,合并读写请求;O_DIRECT的方式对读写的大小有限制,必须是blocksize大小......