Golang文件路径处理与文件夹操作示例

17次阅读

Go中处理文件路径和文件夹操作需使用path</</code></</code>code>code></</code></</code>code>code>/</code></</code>code>filepath</</code></</code>code>code></</code></</code>code>code></</code></</code>code>code></</code></</code>code>code>和os</</code></</code>code>code></</code></</code>code>code>标准库。首先,filepath</</code></</code>code>code></</code></</code>code>code>.Join</</code></</code>code>code>可跨平台拼接路径,避免硬编码分隔符;filepath</</code></</code>code>code></</code></</code>code>code>.Clean能规范化路径,去除冗余的.和..;os</</code></</code>code>code></</code></</code>code>code>.Stat用于判断文件或目录是否存在并获取元信息,配合os</</code></</code>code>code></</code></</code>code>code>.IsNotExist可安全处理不存在的情况;创建多级目录应使用os</</code></</code>code>code></</code></</code>code>code>.MkdirAll,删除目录推荐os</</code></</code>code>code></</code></</code>code>code>.RemoveAll,但需谨慎防止误删;遍历目录内容优先用Go 1.16+的os</</code></</code>code>code></</code></</code>code>code>.ReadDir,效率更高且返回fs.DirEntry</</code>code>信息。关键原则是始终正确处理错误,不假设文件操作必然成功,并区分path</</code></</code>code>code></</code></</code>code>code>(仅/</code></</code>code>分隔)与filepath</</code></</code>code>code></</code></</code>code>code>(系统适配)包的用途。</</code></</code>code>blockquote>

Golang文件路径处理与文件夹操作示例</</code></</code>code>p>

Golang中处理文件路径和进行文件夹操作的核心在于

path</</code></</code>code>code></</code></</code>code>code>/</code></</code>code>filepath</</code></</code>code>code></</code></</code>code>code></</code></</code>code>code></</code></</code>code>code></</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>和

os</</code></</code>code>code></</code></</code>code>code></</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>这两个标准库。它们提供了一套强大且跨平台兼容的工具</</code></</code>code>a>集,让开发者能够以一种稳健的方式管理文件系统,无论是构建配置路径、读写文件,还是进行目录的创建与清理,都离不开它们的身影。理解并熟练运用这些函数,是编写任何涉及文件I/</code></</code>code>O的Go应用的基础。</</code></</code>code>p>

在Go语言中,文件路径处理和文件夹操作主要依赖

path</</code></</code>code>code></</code></</code>code>code>/</code></</code>code>filepath</</code></</code>code>code></</code></</code>code>code></</code></</code>code>code></</code></</code>code>code></</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>和

os</</code></</code>code>code></</code></</code>code>code></</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>这两个标准库。我个人觉得,Go在这方面做得相当务实,它没有引入太多花哨的概念,而是直接提供了我们日常开发中真正需要的工具。</</code></</code>code>p>

解决方案</</code></</code>code>h3>

要处理文件路径和进行文件夹操作,我们需要关注以下几个关键点:路径的构建与解析、目录的创建与删除、文件或目录状态的获取,以及目录内容的遍历。</</code></</code>code>p>

1. 路径的构建与解析</</code></</code>code>strong></</code></</code>code>p>

立即学习</</code></</code>code>span>“/</code></</code>code>/</code></</code>code>pan.quark.cn/</code></</code>code>s/</code></</code>code>00968c3c2c15" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">go语言免费学习笔记(深入)</</code></</code>code>a>”;</</code></</code>code>p>

这是最基础也最容易出错的部分,尤其是涉及到跨平台。我以前总喜欢自己拼接字符串,结果在Windows和Linux之间切换时,路径分隔符的问题总是让我头疼。后来才发现

filepath</</code></</code>code>code></</code></</code>code>code>.Join</</code></</code>code>code></</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>才是王道。</</code></</code>code>p>

package main import ( "fmt" "path</</code></</code>code>code></</code></</code>code>code>/</code></</code>code>filepath</</code></</code>code>code></</code></</code>code>code></</code></</code>code>code></</code></</code>code>code>" "os</</code></</code>code>code></</code></</code>code>code>" ) func main() { /</code></</code>code>/</code></</code>code> 获取当前工作目录 pwd, err := os</</code></</code>code>code></</code></</code>code>code>.Getwd() if err != nil { fmt.Println("获取当前工作目录失败:", err) return } fmt.Println("当前工作目录:", pwd) /</code></</code>code>/</code></</code>code> 拼接路径:filepath</</code></</code>code>code></</code></</code>code>code>.Join</</code></</code>code>code> 会根据操作系统自动选择路径分隔符 /</code></</code>code>/</code></</code>code> 比如在 Linux/</code></</code>code>macOS 上是 /</code></</code>code>,在 Windows 上是 filePath := filepath</</code></</code>code>code></</code></</code>code>code>.Join</</code></</code>code>code>(pwd, "data", "config.txt") fmt.Println("拼接后的文件路径:", filePath) /</code></</code>code>/</code></</code>code> 路径清理:filepath</</code></</code>code>code></</code></</code>code>code>.Clean 可以移除冗余的 /</code></</code>code>../</code></</code>code> 或 /</code></</code>code>./</code></</code>code>,并处理开头的斜杠 /</code></</code>code>/</code></</code>code> 比如 /</code></</code>code>a/</code></</code>code>b/</code></</code>code>../</code></</code>code>c 会变成 /</code></</code>code>a/</code></</code>code>c dirtyPath := "/</code></</code>code>a/</code></</code>code>b/</code></</code>code>../</code></</code>code>./</code></</code>code>c/</code></</code>code>d/</code></</code>code>" cleanPath := filepath</</code></</code>code>code></</code></</code>code>code>.Clean(dirtyPath) fmt.Println("清理前的路径:", dirtyPath) fmt.Println("清理后的路径:", cleanPath) /</code></</code>code>/</code></</code>code> 获取路径的目录和文件名 dir := filepath</</code></</code>code>code></</code></</code>code>code>.Dir(filePath) base := filepath</</code></</code>code>code></</code></</code>code>code>.Base(filePath) ext := filepath</</code></</code>code>code></</code></</code>code>code>.Ext(filePath) fmt.Printf("路径 %s 的目录是 %s, 文件名是 %s, 扩展名是 %sn", filePath, dir, base, ext) }</</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

这里我特别想提一下

path</</code></</code>code>code></</code></</code>code>code></</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>和

filepath</</code></</code>code>code></</code></</code>code>code></</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>两个包的区别。

path</</code></</code>code>code></</code></</code>code>code></</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>包只处理斜杠(

/</code></</code>code></</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>)分隔的路径,不考虑操作系统</</code></</code>code>a>差异,通常用于URL或Unix风格的路径处理。而

filepath</</code></</code>code>code></</code></</code>code>code></</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>才是我们做本地文件系统操作时真正需要的,它会考虑操作系统特性。这个小细节,我第一次踩坑的时候花了点时间才搞明白。</</code></</code>code>p>

2. 目录的创建与删除</</code></</code>code>strong></</code></</code>code>p>

创建目录,尤其是多级目录,

os</</code></</code>code>code></</code></</code>code>code>.MkdirAll</</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>简直是神器,它会递归创建所有不存在的父目录,省去了我们手动判断和创建的麻烦。删除则要小心,

os</</code></</code>code>code></</code></</code>code>code>.RemoveAll</</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>可是个狠角色,直接把整个目录树都删掉。</</code></</code>code>p>

package main import ( "fmt" "os</</code></</code>code>code></</code></</code>code>code>" "path</</code></</code>code>code></</code></</code>code>code>/</code></</code>code>filepath</</code></</code>code>code></</code></</code>code>code></</code></</code>code>code></</code></</code>code>code>" ) func main() { tempDir := "temp_test_dir/</code></</code>code>sub_dir" tempFile := filepath</</code></</code>code>code></</code></</code>code>code>.Join</</code></</code>code>code>(tempDir, "test.txt") /</code></</code>code>/</code></</code>code> 创建多级目录 /</code></</code>code>/</code></</code>code> os</</code></</code>code>code></</code></</code>code>code>.MkdirAll 会创建所有不存在的父目录,如果目录已存在也不会报错 err := os</</code></</code>code>code></</code></</code>code>code>.MkdirAll(tempDir, 0755) /</code></</code>code>/</code></</code>code> 0755 是目录的权限,表示所有者可读写执行,组用户和其他用户可读执行 if err != nil { fmt.Println("创建目录失败:", err) return } fmt.Println("目录创建成功:", tempDir) /</code></</code>code>/</code></</code>code> 创建一个文件用于测试删除 file, err := os</</code></</code>code>code></</code></</code>code>code>.Create(tempFile) if err != nil { fmt.Println("创建文件失败:", err) return } file.Clos</</code></</code>code>code></</code></</code>code>code>e() /</code></</code>code>/</code></</code>code> 记得关闭文件句柄 fmt.Println("文件创建成功:", tempFile) /</code></</code>code>/</code></</code>code> 删除文件 err = os</</code></</code>code>code></</code></</code>code>code>.Remove(tempFile) if err != nil { fmt.Println("删除文件失败:", err) return } fmt.Println("文件删除成功:", tempFile) /</code></</code>code>/</code></</code>code> 删除目录(包括其下的所有文件和子目录) /</code></</code>code>/</code></</code>code> 小心使用 os</</code></</code>code>code></</code></</code>code>code>.RemoveAll,它会递归删除 err = os</</code></</code>code>code></</code></</code>code>code>.RemoveAll("temp_test_dir") if err != nil { fmt.Println("删除目录失败:", err) return } fmt.Println("目录删除成功:", "temp_test_dir") }</</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

3. 文件或目录状态的获取与目录内容遍历</</code></</code>code>strong></</code></</code>code>p>

os</</code></</code>code>code></</code></</code>code>code>.Stat</</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>是获取文件或目录元信息的核心,通过它我们可以判断路径是否存在、是文件还是目录,以及获取修改时间、大小等。遍历目录内容,

os</</code></</code>code>code></</code></</code>code>code>.ReadDir</</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>(Go 1.16+)或者

ioutil.ReadDir</</code>code></</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>(旧版本)都很好用,它们返回的是

fs.DirEntry</</code>code></</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>切片,包含了文件名和类型信息。</</code></</code>code>p>

package main import ( "fmt" "io/</code></</code>code>fs" "os</</code></</code>code>code></</code></</code>code>code>" "path</</code></</code>code>code></</code></</code>code>code>/</code></</code>code>filepath</</code></</code>code>code></</code></</code>code>code></</code></</code>code>code></</code></</code>code>code>" ) func main() { /</code></</code>code>/</code></</code>code> 准备一个目录和一些文件进行测试 testDir := "test_dir_for_stat_and_read" os</</code></</code>code>code></</code></</code>code>code>.MkdirAll(testDir, 0755) os</</code></</code>code>code></</code></</code>code>code>.WriteFile(filepath</</code></</code>code>code></</code></</code>code>code>.Join</</code></</code>code>code>(testDir, "file1.txt"), []byte("hello"), 0644) os</</code></</code>code>code></</code></</code>code>code>.Mkdir(filepath</</code></</code>code>code></</code></</code>code>code>.Join</</code></</code>code>code>(testDir, "sub_dir"), 0755) /</code></</code>code>/</code></</code>code> 获取文件或目录信息 fileInfo, err := os</</code></</code>code>code></</code></</code>code>code>.Stat(testDir) if err != nil { if os</</code></</code>code>code></</code></</code>code>code>.IsNotExist(err) { fmt.Println(testDir, "不存在") } else { fmt.Println("获取文件信息失败:", err) } return } fmt.Printf("%s 是一个目录: %t, 修改时间: %s, 权限: %sn", testDir, fileInfo.IsDir(), fileInfo.ModTime(), fileInfo.Mode()) /</code></</code>code>/</code></</code>code> 遍历目录内容 entries, err := os</</code></</code>code>code></</code></</code>code>code>.ReadDir(testDir) /</code></</code>code>/</code></</code>code> Go 1.16+ if err != nil { fmt.Println("读取目录失败:", err) return } fmt.Printf("目录 %s 的内容:n", testDir) for _, entry := range entries { fmt.Printf(" - %s (是目录: %t)n", entry.Name(), entry.IsDir()) } /</code></</code>code>/</code></</code>code> 清理测试目录 os</</code></</code>code>code></</code></</code>code>code>.RemoveAll(testDir) }</</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

os</</code></</code>code>code></</code></</code>code>code>.IsNotExist(err)</</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>这个判断特别重要,它能帮我们优雅地处理文件或目录不存在的场景,而不是简单地抛出错误。我在生产环境中遇到过不少因为没有正确处理文件不存在而导致程序崩溃的案例,所以这个细节真的不能忽视。</</code></</code>code>p>

在Golang中如何安全地处理跨平台文件路径?</</code></</code>code>h3>

在Go语言中,处理跨平台文件路径,核心思想是避免硬编码</</code></</code>code>a>路径分隔符</</code></</code>code>strong>,并利用标准库提供的抽象</</code></</code>code>strong>。我见过太多新手(包括我早期的自己)直接用字符串拼接

/</code></</code>code></</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>或

</</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>,结果代码一到别的操作系统就出问题。这其实是给自己挖坑。</</code></</code>code>p>

最安全、最推荐的做法是使用

path</</code></</code>code>code></</code></</code>code>code>/</code></</code>code>filepath</</code></</code>code>code></</code></</code>code>code></</code></</code>code>code></</code></</code>code>code></</code></</code>code>pre>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>

</</code></</code>code>div></</code></</code>code>div>包。这个包的设计就是为了解决跨平台路径问题。</</code></</code>code>p>

/</code></</code>code>/</code></</code>code>phps.yycxw.com/</code></</code>code>ai/</code></</code>code>airops">Golang文件路径处理与文件夹操作示例</</code></</code>code>a>

/</code></</code>code>/</code></</code>code>phps.yycxw.com/</code></</code>code>ai/</code></</code>code>airops">AirOps</</code></</code>code>a>

AirOps帮助业务团队使用正确的数据创建表、文档和工具</</code></</code>code>p>

Golang文件路径处理与文件夹操作示例20</</code></</code>code>span> </</code></</code>code>div> </</code></</code>code>div> /</code></</code>code>/</code></</code>code>phps.yycxw.com/</code></</code>code>ai/</code></</code>code>airops"> 查看详情</</code></</code>code>span> Golang文件路径处理与文件夹操作示例</</code></</code>code>a> </</code></</code>code>div>