1. 简介
目录生成器是一个十分实用的工具,可以自动将指定目录下的文件以及文件夹生成为一个目录结构,方便用户查看和定位文件。在本文中,我们将使用 Go 语言开发一个简易的目录生成器。
2. 项目搭建
2.1 Go 语言环境安装
在开始项目之前,我们需要安装 Go 语言环境。
可以在 Go 官网上下载对应操作系统的 安装包, 安装完成之后,输入以下命令验证是否安装成功:
go version
如果可以正常输出当前 Go 的版本,那么就说明安装成功。
2.2 项目初始化
使用命令行进入一个新的目录,创建一个新的 Go 项目, 并且初始化该项目:
mkdir DirGenerator
cd DirGenerator
go mod init dir_generator
这样,一个名为 DirGenerator 的项目就创建好了,并且使用了 dir_generator 作为该项目库的名称,方便之后的依赖管理。
3. 代码实现
3.1 遍历文件夹
遍历指定的目录,并且将文件以及文件夹名字记录在字符串 slice 中。代码如下:
// 遍历指定路径的文件夹,将文件夹和文件名放到 targetPaths 数组中
func traverseFolder(path string, targetPaths *[]string) error {
list, err := ioutil.ReadDir(path)
if err != nil {
return err
}
// 遍历该路径下的文件或文件夹
for _, item := range list {
targetPaths = append(targetPaths, path+"/"+item.Name())
if item.IsDir() {
err = traverseFolder(path+"/"+item.Name(), targetPaths)
if err != nil {
return err
}
}
}
return err
}
func traverseFolder(path string, targetPaths *[]string) error 这个函数用于遍历指定的目录并且将文件名和文件夹名保存到目标数组中。其中,path 是指定的文件夹路径,targetPaths 则是保存文件夹名和文件名的目标数组。
在函数内部,err := ioutil.ReadDir(path) 可以返回一个文件夹的列表,其类型是 []os.FileInfo。然后我们可以遍历这个列表中的每一个条目,并且将文件或文件夹名记录在 targetPaths 数组中。如果当前条目是文件夹,我们再递归调用该函数来继续遍历该文件夹。如果遍历过程中出现错误,将会在遍历结束后通过返回值传递给调用者。
3.2 目录生成函数
使用上面的 traverseFolder 函数,我们可以获取到指定目录下的所有文件和文件夹的名字。下面编写一个函数,该函数接受一个字符串 slice (保存有文件以及文件夹名字),并且将其以目录结构的形式打印出来:
// 打印目录结构
func printDirectoryTree(targetPaths *[]string) {
dirMap := make(map[string][]string)
var directories []string
// 遍历 targetPaths 中的路径
for _, path := range *targetPaths {
dir, fileName := filepath.Split(path)
if dir == "" {
dir = "."
}
// 该路径为文件
if fileName != "" {
dirMap[dir] = append(dirMap[dir], fileName)
} else {
// 该路径为文件夹
directories = append(directories, dir)
}
}
// 对文件夹进行排序
sort.Strings(directories)
for _, directory := range directories {
printIndent(0)
fmt.Println(directory)
printDirContent(dirMap[directory], 0)
}
}
// 打印目录结构子目录
func printDirContent(content []string, depth int) {
depth += 1
sort.Strings(content)
for index, item := range content {
printIndent(depth)
fmt.Println("|---", item)
// 如果当前条目为最后一项,则最后的竖线为单独一行,否则为分割线
if index == len(content)-1 {
printDirContent(nil, depth)
} else {
printDirContent(nil, depth)
printIndent(depth)
fmt.Println("|")
}
}
}
// 打印缩进
func printIndent(depth int) {
for j := 0; j < depth; j++ {
fmt.Print("| ")
}
}
该 printDirectoryTree 函数接受一个字符串 slice 作为参数,然后遍历 slice 中的路径,判断该路径是文件还是文件夹。如果是已知文件夹(路径中最后一个为 /)则放到一个数组中,在程序输出时按照字典序排序;如果是已知文件,则放到一个映射表 dirMap 中,该映射表以文件夹路径为 key,文件名列表为 value。
使用递归函数 printDirContent 来输出每一个文件夹的目录结构。在 printDirContent 中,我们判断输入的数组是否为空,如果是的话,则代表该是目录的竖线位于最后,单独一个行输出;否则,输出分割线以及文件夹结构。
4. 测试
为了能够测试刚才编写的目录生成器,我们需要从命令行传入一个文件目录。在main函数中通过命令行参数获取目录名后,调用 traverseFolder 函数获取文件路径列表,最后调用 printDirectoryTree 函数以目录结构列表的形式打印出结构信息。
完整主函数代码如下:
func main() {
// 获取命令行参数:第一个是程序,第二个才是目标路径
args := os.Args
if len(args) != 2 {
fmt.Println("请输入目标路径")
return
}
dirPath := args[1]
var targetPaths []string
err := traverseFolder(dirPath, &targetPaths)
if err != nil {
fmt.Printf("获取路径列表错误:%v\n", err)
return
}
printDirectoryTree(&targetPaths)
}
测试时,我们可以在命令行执行以下命令:
go run main.go /home/user/Desktop
其中 /home/user/Desktop 为你的文件夹路径,这里仅作为示例。运行后,控制台将会显示 该目录的目录结构,如下图所示:
/home/user/Desktop
|---another.subdirectory
| |---testfile3.txt
|---subdirectory
| |---testfile2.txt
|---testfile1.txt
5.总结
在本文中,我们使用 Go 语言实现了一个简易的目录生成器,并且演示了如何遍历指定目录下的文件夹并以树形结构输出。同时,还介绍了如何使用命令行参数传递目标路径,以及如何使用递归和映射表来实现打印目录结构。
希望本文能够帮助您更好地了解 Go 语言的相关技巧和知识点,并且带给您实战中的启示。