golang - go语言在遍历目录的时候删除空目录,一个很奇怪的现象
本文介绍了golang - go语言在遍历目录的时候删除空目录,一个很奇怪的现象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
问 题
测试平台:CentOS7.2
代码:
package main
import (
"os"
"fmt"
"path/filepath"
)
func main(){
path:="/opt/test"
handlefunc:=func(file_path string , f os.FileInfo , err error) error{
fmt.Println("I am ",file_path)
if f.IsDir(){
//os.Remove(file_path)
//fmt.Println("Empty Dir , deleted !")
}
fmt.Println("\n")
return nil
}
fi , _ := os.Stat(path)
if fi.IsDir(){
filepath.Walk(path,handlefunc)
}
}
目录 /opt/test的结构如下
注意上面的代码有两行被注释掉了,这种情况下我得到了想要的输出:
然而我把注释打开再运行之后,竟然出现这样的输出:
【问题】
发现没,空目录'/opt/one/two'被打印了两次,明明第一次被删除了才对,为什么会出现这样的情况???
解决方案
下面代码是filepath.Walk的实现源码
func walk(path string, info os.FileInfo, walkFn WalkFunc) error {
// path=/opt/test/one/two 此时运行第一次walkFn,删除目录成功
err := walkFn(path, info, nil)
if err != nil {
if info.IsDir() && err == SkipDir {
return nil
}
return err
}
//你写的handle里默认返回nil,所以会继续往下走
//info为/opt/test/one/two 为目录此处不走
if !info.IsDir() {
return nil
}
//因为上面已经把two删除,此处读取会失败,err为找不到目录/opt/test/one/two
names, err := readDirNames(path)
if err != nil {
//失败之后又调用了一次你写的hanndel,传入的path还是/opt/test/one/two 这就是第二次的原因。
return walkFn(path, info, err)
}
for _, name := range names {
filename := Join(path, name)
fileInfo, err := lstat(filename)
if err != nil {
if err := walkFn(filename, fileInfo, err); err != nil && err != SkipDir {
return err
}
} else {
err = walk(filename, fileInfo, walkFn)
if err != nil {
if !fileInfo.IsDir() || err != SkipDir {
return err
}
}
}
}
return nil
}
从代码看出内部使用的是递归
直接看最底层目录 /opt/test/one/two
walk传入path=/opt/test/one/two
看我给加的代码注释应该就明白了
不明白在问我。
这篇关于golang - go语言在遍历目录的时候删除空目录,一个很奇怪的现象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文