Go 1.19.4 路径和目录-Day 15

news2024/11/14 10:35:50

1. 路径介绍

存储设备保存着数据,但是得有一种方便的模式让用户可以定位资源位置,操作系统采用一种路径字符 串的表达方式,这是一棵倒置的层级目录树,从根开始。

  • 相对路径:不是以根目录开始的路径,例如 a/b 、 a/b/c 、 . 、 ../a/b 、 ./a/b/c
  • 绝对路径:以斜杆开始的路径,例如 /a/b 、 /a/b/c 、 /t/../a/b ,window需要盘符 e:\a\b\c
  • 路径分隔符:windows为 \ ,但是也支持 / ;Linux系统等为 /

2. 路径处理包

为了方便处理,Go语言标准库提供path包和更加方便的path/filepath包,使用filepath即可。

3. 路径拼接(filepath.Join)

作用:

        由于路径是字符串,直接使用字符串拼接就可以了,也可以使用filepath.Join方法。

        推荐使用filepath.Join,这个函数会将多个字符串参数组合成一个路径,并且会根据操作系统的要求,自动插入正确的路径分隔符。

语法:

        func filepath.Join(elem ...string) string

参数:

        elem ...string:相对路径或者绝对路径。

返回值:

        string:合并后的完整路径。

package main

import (
	"fmt"
	"path/filepath"
)

func main() {
	p1 := "/a/b" + "/" + "c/d" + "/" + "f"

    // 就算写错了分隔符,filepath.Join也会自动处理为正确的
	p2 := filepath.Join("a/b", "c/d", "f") // 相对路径
    p3 := filepath.Join("/a", "b", "c") // 绝对路径

	fmt.Println(p1)
	fmt.Println(p2)

}
=============调试结果=============
/a/b/c/d/f
a\b\c\d\f
\a\b\c

4. 路径分解

就是提取完整路径中的某一部分。

4.1 提取目录(filepath.Dir)

作用:

        filepath.Dir 函数用于从完整的文件路径中提取目录部分。这个函数会返回给定路径中,文件名之前的目录路径。

语法:

        func filepath.Dir(path string) string

参数:

        表示完整的文件路径。

返回值:

        string:成功提取的目录部分。

package main

import (
	"fmt"
	"path/filepath"
)

func main() {
	// 注意a前面没有/,所以是个相对路径
	fmt.Println("======filepath.Join======")
	p1 := filepath.Join("a/b", "c/d", "f", "mysql.ini")
	fmt.Printf("p1的类型=%T\np1的值=%+[1]v\n", p1)
	fmt.Println("======filepath.Dir======")
	dir := filepath.Dir(p1) // 提取目录
	fmt.Printf("dir=%s\n", dir)
}
======filepath.Join======
p1的类型=string
p1的值=a\b\c\d\f\mysql.ini
======filepath.Dir======
dir=a\b\c\d\f

4.2 提取文件扩展名(filepath.Ext)

作用:

        Ext返回path使用的文件扩展名。扩展是path的最后一个元素的最后一个点开始的后缀;如果没有点,则为空。

语法:

        func filepath.Ext(path string) string

参数:

      path string:文件路径变量。

返回值:

          string:返回截取到的文件扩展名。

package main

import (
	"fmt"
	"path/filepath"
)

func main() {
	// 注意a前面没有/,所以是个相对路径
	fmt.Println("======filepath.Join======")
	p1 := filepath.Join("a/b", "c/d", "f", "mysql.ini")
	fmt.Printf("p1的类型=%T\np1的值=%+[1]v\n", p1)
	fmt.Println("======filepath.Ext======")
	dir := filepath.Ext(p1)
	fmt.Printf("dir=%s", dir)
}
======filepath.Join======
p1的类型=string
p1的值=a\b\c\d\f\mysql.ini
======filepath.Ext======
dir=.ini

4.3 提取文件名(filepath.Base)

作用:

        filepath.Base 函数用于从完整的文件路径中提取文件名部分。这个函数会返回给定路径中的最后一个元素,即文件名或目录名。

语法:

        func filepath.Base(path string) string

参数:

        path string:完整的文件路径。

返回值:

        string:表示从给定路径中提取的最后一个元素,即文件名或目录名。

import (
	"fmt"
	"path/filepath"
)

func main() {
	// 提取文件名
	base := filepath.Base("path/to/the/file.txt")
	fmt.Println(base) // 输出: file.txt

	// 处理绝对路径
	baseAbsolute := filepath.Base("/home/user/file.txt")
	fmt.Println(baseAbsolute) // 输出: file.txt

	// 处理只有目录没有文件名的路径
	baseDir := filepath.Base("path/to/")
	fmt.Println(baseDir) // 输出: (空字符串,因为路径以斜杠结尾)

	// 处理根目录
	baseRoot := filepath.Base("/home")
	fmt.Println(baseRoot) // 输出: home

	// 处理没有目录的文件名
	baseNoDir := filepath.Base("file.txt")
	fmt.Println(baseNoDir) // 输出: file.txt

	// 处理隐藏文件
	baseHidden := filepath.Base(".hiddenfile")
	fmt.Println(baseHidden) // 输出: .hiddenfile
}

5. 目录

5.1 获取当前工作目录(os.Getwd)

作用:

        Getwd返回与当前目录对应的根路径名(注意是程序的运行目录)。如果当前目录可以通过多个路径到达(由于符号链接),Getwd可能返回其中的任何一个。

语法:

        func os.Getwd() (dir string, err error)

返回值:

        dir string:表示当前工作目录的路径。

        err error:如果发生错误,返回错误对象;否则返回 nil

package main

import (
	"fmt"
	"os"
)

func main() {
	dir, err := os.Getwd()
	if err != nil {
		panic(err)
	} else {
		fmt.Printf("当前工作目录=%s", dir) 
	}
}
=======调试结果=======
当前工作目录=d:\个人\GO开发\20240624

5.2 获取当前登录用户的家目录(os.UserHomeDir)

作用:

        os.UserHomeDir 函数用于获取当前用户的主目录路径。

        os.UserHomeDir 在不同的操作系统上都能正常工作,它会根据操作系统的环境变量(如 HOME 在 Unix 系统上,USERPROFILE 或 HOMEPATH 在 Windows 系统上)来确定用户的主目录。
 

语法:

        func UserHomeDir() (string, error)

返回值:

        string:表示当前用户的主目录路径。

        error:如果发生错误,返回错误对象;否则返回 nil

package main

import (
	"fmt"
	"os"
)

func main() {
	s, err := os.UserHomeDir()
	if err != nil {
		panic(err)
	} else {
		fmt.Printf("当前登录用户家目录=%s", s)
	}
}
=======调试结果=======
当前登录用户家目录=C:\Users\123456

6. 绝对路径

6.1 判断绝对路径(filepath.IsAbs)

作用:

        filepath.IsAbs 函数用于检查给定的路径是否是绝对路径。

语法:

        func filepath.IsAbs(path string) (b bool)

参数:

      path string:  表示要检查的文件路径。

返回值:

        b bool:如果路径是绝对路径,则返回 true;否则返回 false

package main

import (
	"fmt"
	"path/filepath"
)

func main() {
	p1 := filepath.Join("a/b", "c/d", "f", "mysql.ini")
	fmt.Printf("p1的路径=%s\n", p1)

	path := filepath.IsAbs(p1)
	fmt.Printf("p1是否为绝对路径=%v", path)
}
=====调试结果=====
p1的路径=a\b\c\d\f\mysql.ini
p1是否为绝对路径=false

6.2 将相对路径转换为绝对路径(filepath.Abs)

作用:

        filepath.Abs 函数用于将相对路径转换为绝对路径。

        它根据当前工作目录(程序运行目录)和提供的相对路径来计算绝对路径。

语法:

        func filepath.Abs(path string) (string, error)

参数:

        path string:表示要转换的相对文件路径。

返回值:

        string:表示转换后的绝对路径。

        error:如果发生错误,返回错误对象;否则返回 nil

package main

import (
	"fmt"
	"path/filepath"
)

func main() {
	p1 := filepath.Join("a/b", "c/d", "f", "mysql.ini")
	fmt.Printf("p1的路径=%s\n", p1)

	abs, err := filepath.Abs(p1)
	if err != nil {
		panic(err)
	} else {
		fmt.Printf("Abs处理后的绝对路径=%s", abs)
	}
}
=====调试结果=====
p1的路径=a\b\c\d\f\mysql.ini
Abs处理后的绝对路径=d:\个人\GO开发\20240624\a\b\c\d\f\mysql.ini

7. 存在性检测

7.1 获取文件或目录信息(os.Stat)

作用:

        os.Stat 函数用于获取文件或目录的状态信息。这个函数是 os 包的一部分,它返回一个 fs.FileInfo 接口,该接口提供了文件的大小、修改时间、权限等信息。

语法:

        func os.Stat(name string) (fs.FileInfo, error)

参数:

    name string:表示要获取状态信息的文件或目录的路径。

返回值:

        fs.FileInfo:一个实现了 FileInfo 接口的对象,包含了文件或目录的详细信息。

        error:如果发生错误,返回错误对象;否则返回 nil

package main

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

func main() {
	p1 := filepath.Join("a/b", "c/d", "f", "mysql.ini")
	fmt.Printf("p1的路径=%s\n", p1)

	fi, err := os.Stat(p1)
	if err != nil {
		fmt.Println("获取文件信息异常:", err)
	} else {
		fmt.Println(fi)
	}
}
=====调试结果=====
p1的路径=a\b\c\d\f\mysql.ini
获取文件信息异常: CreateFile a\b\c\d\f\mysql.ini: The system cannot find the path specified.

7.2 检测文件或目录是否存在

7.2.1 os.IsNotExist

作用:

        os.IsNotExist 函数用于检查一个错误是否表示文件或目录不存在的错误。

语法:

        func os.IsNotExist(err error) bool

参数:

        err error:表示要检查的错误对象。

返回值:

        bool:如果错误表示文件已存在,则返回 true;否则返回 false

package main

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

func main() {
	fmt.Println("==========调试结果==========")

	p1 := filepath.Join("a/b", "c/d", "f", "mysql.ini")
	fmt.Printf("p1的路径=%s\n", p1)

	fi, err := os.Stat(p1)
	if err != nil {
		fmt.Printf("获取文件信息异常:%s\n文件不存在:%v\n", err, os.IsNotExist(err))
	} else {
		fmt.Println(fi)
	}
}
==========调试结果==========
p1的路径=a\b\c\d\f\mysql.ini
获取文件信息异常:CreateFile a\b\c\d\f\mysql.ini: The system cannot find the path specified.
文件不存在:true

8. 创建目录和文件

8.1 创建目录

创建目录主要有这3个函数:

  1. os.Mkdir
    创建一个新的子目录,父目录必须存在,否则报错。
  2. os.MkdirAll
    递归创建一个目录路径。
  3. os.MkdirTemp
    创建一个临时目录。

8.1.1 os.MkdirAll

作用:

        os.MkdirAll 函数是 Go 语言标准库 os 包中的一个函数,用于递归创建一个目录路径,包括任何必要的中间目录。这个函数非常适合在需要确保整个目录结构都存在时使用,例如在创建文件之前。

        创建时,如果用的是相对路径,则会在程序所在目录下创建。

        目录已存在,创建也不会报错。

语法:

        func os.MkdirAll(path string, perm fs.FileMode) error

参数:

        path string:要创建的目录路径,可以包含多级目录。

        perm fs.FileMode:设置目录的权限。fs.FileMode 是一个类型,通常使用常量如 fs.ModePerm来表示权限,也可以手动指定权限如0755

返回值:

        error:如果所有目录都成功创建,则返回 nil;如果发生错误(例如,权限不足),则返回错误对象。

package main

import (
	"fmt"
	"os"
)

func main() {
	fmt.Println("==========调试结果==========")
	
	err := os.MkdirAll("d:/个人/学习/Go/文件与目录操作/创建测试", os.ModePerm) // os.ModePerm默认权限为511
    // err := os.MkdirAll("创建测试", os.ModePerm)// 如果是相对路径,则会在程序所在目录下创建
	if err != nil {
		fmt.Println("目录创建失败:", err)
	} else {
		fmt.Println("递归创建目录成功!")
	}
}
==========调试结果==========
递归创建目录成功!

8.2 创建文件

创建文件可以使用os包中的两个函数:

  • os.Create
    注意:如果文件已经存在了,该函数会先清空文件中原本的内容,再创建。
  • os.OpenFile
    OpenFile能够更细粒度的去控制文件的权限。

8.2.1 os.Create

package main

import (
	"fmt"
	"os"
)

func main() {
	fmt.Println("==========调试结果==========")

	f, err := os.Create("d:/个人/学习/Go/文件与目录操作/创建测试/create-test.txt")
	if err != nil {
		panic(err)
	}
	fmt.Println("文件创建成功!")
	defer f.Close()
}
==========调试结果==========
文件创建成功!

9. 获取文件或目录元数据信息(Stat)

除了利用stat来判断文件是否存在,还可以检测文件元数据,如判断是否为目录、是否为文件、文件权限、大小、修改时间等。

package main

import (
	"fmt"
	"os"
)

func main() {
	fmt.Println("==========调试结果==========")

	p1 := "d:/个人/学习/Go/文件与目录操作/创建测试/create-test.txt"
	fi, err := os.Stat(p1)
	if err != nil {
		panic(err)
	} else {
		fmt.Printf("文件名=%s\n是否为目录=%v\n文件的权限=%v\n文件的大小=%d\n文件的修改时间=%s\n", fi.Name(), fi.IsDir(), fi.Mode(), fi.Size(), fi.ModTime())
	}
}
==========调试结果==========
文件名=create-test.txt
是否为目录=false
文件的权限=-rw-rw-rw-
文件的大小=0
文件的修改时间=2024-09-04 15:44:45.291237 +0800 CST

10. 遍历目录

10.1 os.ReadDir(非递归遍历)

作用:

        读取指定目录下的所有条目(包括文件和子目录),非递归。

语法:

        func os.ReadDir(name string) ([]fs.DirEntry, error)

参数:

        name string:要读取的目录的路径。

返回值:

        []fs.DirEntry:一个包含 fs.DirEntry 接口的切片,每个条目代表目录中的一个文件或子目录。

        error:如果读取目录过程中发生错误,则返回错误对象;否则返回 nil

package main

import (
	"fmt"
	"os"
)

func main() {
	fmt.Println("==========调试结果==========")

	de, err := os.ReadDir("D:/个人/学习/Go/文件与目录操作")
	if err != nil {
		panic(err)
	}
	fmt.Println(de)
	for i, v := range de {
		fmt.Println(i, v, v.Name(), v.Type(), v.IsDir())
	}
}
==========调试结果==========
[{0xc00010a000} {0xc00010a070}]
0 {0xc00010a000} test.txt ---------- false
1 {0xc00010a070} 创建测试 d--------- true

10.2 filepath.WalkDir(递归遍历)

作用:

        用于递归遍历一个目录及其所有子目录中的文件和子目录。

语法:

        func filepath.WalkDir(root string, fn fs.WalkDirFunc) error

参数:

        root string:要遍历的根目录的路径。

        fn fs.WalkDirFunc:一个回调函数,用于处理每个文件和目录。它接收三个参数:当前遍历到的路径、一个 fs.DirEntry 对象(包含文件或目录的信息),以及在读取目录时可能发生的错误。

返回值:

        error:如果遍历过程中发生错误,则返回错误对象;否则返回 nil

package main

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

func main() {
	fmt.Println("==========调试结果==========")
	
	filepath.WalkDir(
		"D:/个人/学习/Go/文件与目录操作",
		func(path string, d fs.DirEntry, err error) error {
			fmt.Println(path, d.Name(), d.IsDir())
			return err
		}) // path string,就是遍历过程中遍历到的文件或目录
}
==========调试结果==========
D:/个人/学习/Go/文件与目录操作 文件与目录操作 true
D:\个人\学习\Go\文件与目录操作\test.txt test.txt false
D:\个人\学习\Go\文件与目录操作\创建测试 创建测试 true
D:\个人\学习\Go\文件与目录操作\创建测试\create-test.txt create-test.txt false

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2158374.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

torch.nn系列函数学习 --- Conv2d函数

该函数的官方文档: https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html#torch.nn.Conv2d torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride1, padding0, dilation1, groups1, biasTrue, padding_modezeros, deviceNone, dtypeNone)…

排序题目:将矩阵按对角线排序

文章目录 题目标题和出处难度题目描述要求示例数据范围 前言解法思路和算法代码复杂度分析 题目 标题和出处 标题:将矩阵按对角线排序 出处:1329. 将矩阵按对角线排序 难度 5 级 题目描述 要求 矩阵对角线是一条从矩阵最上面行或者最左侧列中的某…

CentOS Linux教程(6)--CentOS目录

文章目录 1. 根目录2. cd目录切换命令3. CentOS目录介绍4. pwd命令介绍5. ls命令介绍5.1 ls5.2 ls -a5.3 ls -l 1. 根目录 Windows电脑的根目录是计算机(我的电脑),然后C盘、D盘。 Linux系统的根目录是/,我们可以使用cd /进入根目录,然后使…

共享打印机,局域网搜不到

如果共享打印机后,局域网内其余机器检索不到 1. 排查 是否启用来宾账户(Guest) 2. 网络和共享中心->更改高级共享设置->启用网络发现、启用文件和打印机共享、关闭密码保护共享 排查基本可以解决搜索不到打印机问题

Transformer动画讲解

**Transformer工作原理**** **一、**** ******GPT的核心是Transformer******** *GPT* : **GPT(Generative Pre-trained Transformer)**** ****是一种基于单向Transformer解码器的预训练语言模型,它通过在大规模语料库上的无监督…

MatrixOne 助力某电信运营商构建低成本高性能车联网管理系统

客户基本情况 该电信运营商在物联网领域深耕多年,致力于为企业和个人提供全面的物联网解决方案,包括智能连接、设备管理、数据采集与分析等核心服务。凭借其强大的网络覆盖和技术优势,该运营商为各行业提供高效、安全、可靠的物联网服务&…

风速传感器一文浅谈 了解自然的力量

产品概述 本产品主要采用优质聚合物碳纤维为原材料,具有良好的防腐、防侵蚀等特点,能够保证仪器长期使用不起锈,同时配合内部顺滑的轴承系统,确保了信息采集的准确性。外型小巧轻便,便于携带和组装,三杯设…

MCU和YT9218交换机通过RMII连接

1、可以通过带RMII的MCU和EXT1端口连接,将MCU配置为RMII 100M/全双工就可以通 2、原先在这里改SW配置, 一直不通 3、后来通过api调用可以通 这样改: 在初始化后,添加下面代码 //使能RMII,phy模式 #define Port5 …

【LeetCode】动态规划—使用最小花费爬楼梯(附完整Python/C++代码)

动态规划—#746. 使用最小花费爬楼梯 前言题目描述基本思路1. 问题定义:2. 理解问题和递推关系:3. 解决方法:4. 进一步优化:5. 小总结: 代码实现Python3代码实现Python 代码解释C代码实现C 代码解释 总结: 前言 在这个问题中,我们有一个数组 c o s t [ ] cost[] c…

单细胞SCENIC简单可视化分析学习和整理

SCENIC教程中给出三个方法进行下游的可视化分析,分别可以选择网页(SCope)平台,R或者python进行分析。 1、网页版:https://scope.aertslab.org/ 把数据从左侧工具栏处上传之后就可以个性化分析了~ 2、R和Python就殊途同归啦~ 笔者基于githu…

linux/CentOS 开机启动程序

前言 TencentOS Server 3.1 (TK4)适用于自己编写启动脚本的情况 编写启动脚本 比如启动tomcat,kaijiqidong_tomcat.sh #!/bin/bashecho "kaijiqidong_tomcat on date ." >> kaijiqidong_tomcat.log 2>&1cd /x/xx/xxx sh /x/tomcat/bin/s…

老照片修复软件有哪些?6个工具轻松搞定

在回忆的长廊中,老照片承载着岁月的痕迹和珍贵的记忆。 然而,时间的流逝往往让这些宝贵的瞬间变得模糊不清。幸运的是,现代科技赋予了我们修复这些老照片的能力。 面对市场上众多的老照片自动修复软件,选择一个合适的工具变得尤…

Apache APISIX学习(1):介绍、docker启动

一、介绍 Apache APISIX 是一个动态、实时、高性能的 API 网关, 提供负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。你可以把 Apache APISIX 当做流量入口,来处理所有的业务数据,包括动态路由、动态上游…

得物自建 Redis 无人值守资源均衡调度设计与实现

目录: 一、为什么要做资源均衡调度 二、为什么要做自动化资源均衡调度 三、如何合理选择迁移节点 四、如何保障迁移过程中可靠性1. 添加从节点2. 检查同步数据正常3. 执行主从切换4. 检查主从切换正常5. 删除待迁移节点6. 消息通知 五、迁移任务管理展示 六、总结 …

户用光伏项目难管理,到底该怎么办?

一、鹧鸪云光伏业务管理软件:一站式管理利器 鹧鸪云光伏业务管理软件,作为一款专为光伏行业量身定制的智能化管理工具,集成了项目管理、运维管理、数据分析、用户服务等多功能模块于一体,旨在通过数字化手段,实现户用…

Nature Genetics|三代测序微量建库技术:媲美WGBS的直接甲基化检测

DNA修饰和甲基化是理解基因调控机制的关键。以往,我们的经验表明,使用三代测序从未经扩增的长DNA模板中同时读取序列信息和碱基修饰,需要投入大量的DNA样本来构建文库。 今天,小编带大家看一篇2024年发表于《Nature Genetics》的…

【MAUI】FlexLayout

文章目录 概述属性方向和对齐方式DirectionWrapJustifyContentAlignItemsAlignContent 圣杯布局来源 概述 FlexLayout弹性布局,和前端的Flex弹性布局,几乎一样。FlexLayout是容器,可以定义Direction/主轴方向、Wrap/子元素在主轴方向上是否换…

Vue使用Vue Router路由:开发单页应用

1、路由基础 在单页 Web 应用中,整个项目只有一个 HTML 文件,不同视图(组件的模块)的内容都是在同一个页面中渲染的。当用户切换页面时,页面之前的跳转都是在浏览器端完成的,这时就需要使用前端路由。 路…

蒙古语有方言差异吗?

蒙古语存在方言差异,主要分为西部方言和东部方言两大类。西部方言,即蒙古方言或喀尔喀方言,主要在蒙古国使用,是该国的官方语言。东部方言,又称布里亚特方言或巴尔虎-布里亚特方言,主要在中国内蒙古自治区和…

deepin桌面版连接windows远程桌面

在Linux系统中,要登录到Windows系统,通常可以使用远程桌面协议(RDP)。你需要在Linux系统上安装RDP客户端。 使用如下命令安装rdp协议: sudo apt-get install xrdp 安装成功后,启动rdp服务。 sudo systemctl start xrdp 有了r…