引子
某位同事小哥哥找到我,说领导让他把收集到全国各地的文章整理一下,有的地区的文章在别的地区里,比较急,让我帮忙想想办法,我立马去百度找了个windows文件树查看,他说要复制到表格里,默认的不行,让我给他写一个,想了想go可以直接生成不同端的不同文件,不用额外安装运行环境,开搞开搞
用到的库
- flag 命令行工具,解析参数;
- bufio 通过缓存来提高效率,缓存放在主存中;
- os 包之目录和文件(file)的操作;
功能
可以通过命令行指定输出文件还是文件夹树,并且输出到txt,便于复制
代码
主入口
func main() {
var folder bool
var document bool
var rootPath string
flag.BoolVar(&folder, "r", true, "文件夹")
flag.BoolVar(&document, "d", false, "文件")
flag.StringVar(&rootPath, "rp", "", "要遍历的根文件夹")
flag.Parse()
if rootPath == "" {
exPath, _ := os.Getwd()
rootPath = exPath
}
filePath := "out.txt"
var err = os.Remove(filePath)
_, err1 := os.Create(filePath)
if err != nil {
return
}
if err != nil && err1 != nil {
return
}
file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
fmt.Println("文件打开失败", err)
}
// 及时关闭file句柄
defer func(file *os.File) {
err = file.Close()
}(file)
write := bufio.NewWriter(file)
getPath(folder, document, rootPath, "", write)
}
文件树逻辑
func getPath(folder bool, document bool, rootPath string, indent string, write *bufio.Writer) {
files, err := ioutil.ReadDir(rootPath)
if err != nil {
fmt.Println("read file path error", err)
return
}
for i := 0; i < len(files); i++ {
if files[i].Name()[0] == '.' {
files = append(files[:i], files[i+1:]...)
}
}
dirs := make([]string, 0)
if document {
for _, fi := range files {
if !fi.IsDir() {
dirs = append(dirs, fi.Name())
}
}
}
lenFile := len(dirs)
if folder {
for _, fi := range files {
if fi.IsDir() {
dirs = append(dirs, fi.Name())
}
}
}
// 最后一个文件的分支用
for i := 0; i < len(dirs); i++ {
if i == len(dirs)-1 {
fmt.Println(indent + "└── " + dirs[i])
_, err := write.WriteString(indent + "└── " + dirs[i] + "\r\n")
if err != nil {
return
}
e := write.Flush()
if e != nil {
return
}
if i >= lenFile {
getPath(folder, document, rootPath+"/"+dirs[i], indent+" ", write)
}
} else {
fmt.Println(indent + "├── " + dirs[i])
_, err := write.WriteString(indent + "├── " + dirs[i] + "\r\n")
if err != nil {
return
}
e := write.Flush()
if e != nil {
return
}
if i >= lenFile {
getPath(folder, document, rootPath+"/"+dirs[i], indent+"│ ", write)
}
}
}
}
使用
go run main.go file_name.go
参数
-r 指定显示文件夹
-d 指定显示文件
-rp 指定要便利的文件夹 (默认当前路径)