加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

go – 并发文件系统扫描

发布时间:2020-12-15 04:38:56 所属栏目:Java 来源:网络整理
导读:我想获取目录中文件的文件信息(文件名和大小,以字节为单位).但是有很多子目录(~1000)和文件(~40 000). 实际上我的解决方案是使用filepath.Walk()来获取每个文件的文件信息.但这很长. func visit(path string,f os.FileInfo,err error) error { if f.Mode().I
我想获取目录中文件的文件信息(文件名和大小,以字节为单位).但是有很多子目录(~1000)和文件(~40 000).

实际上我的解决方案是使用filepath.Walk()来获取每个文件的文件信息.但这很长.

func visit(path string,f os.FileInfo,err error) error {
    if f.Mode().IsRegular() {
        fmt.Printf("Visited: %s File name: %s Size: %d bytesn",path,f.Name(),f.Size())
    }
    return nil
}
func main() {
    flag.Parse()
    root := "C:/Users/HERNOUX-06523/go/src/boilerpipe" //flag.Arg(0)
    filepath.Walk(root,visit)
}

是否可以使用filepath.Walk()进行并行/并发处理?

解决方法

您可以通过修改visit()函数来进行并发处理,不要进入子文件夹,而是为每个子文件夹启动一个新的goroutine.

为此,如果条目是目录,则从visit()函数返回特殊的filepath.SkipDir错误.不要忘记检查visit()中的路径是否是goroutine应该处理的子文件夹,因为它也传递给visit(),如果没有这个检查,你将无休止地为初始文件夹启动goroutines.

此外,您还需要某种“计数器”,表示有多少goroutine仍然在后台工作,因为您可以使用sync.WaitGroup.

这是一个简单的实现:

var wg sync.WaitGroup

func walkDir(dir string) {
    defer wg.Done()

    visit := func(path string,err error) error {
        if f.IsDir() && path != dir {
            wg.Add(1)
            go walkDir(path)
            return filepath.SkipDir
        }
        if f.Mode().IsRegular() {
            fmt.Printf("Visited: %s File name: %s Size: %d bytesn",f.Size())
        }
        return nil
    }

    filepath.Walk(dir,visit)
}

func main() {
    flag.Parse()
    root := "folder/to/walk" //flag.Arg(0)

    wg.Add(1)
    walkDir(root)
    wg.Wait()
}

一些说明:

根据子文件夹中文件的“分布”,这可能无法充分利用您的CPU /存储,就好像例如99%的所有文件都在一个子文件夹中一样,goroutine仍将花费大部分时间.

另请注意,fmt.Printf()调用是序列化的,因此也会减慢进程的速度.我假设这只是一个例子,实际上你会在内存中进行某种处理/统计.不要忘记还保护对从visit()函数访问的变量的并发访问.

不要担心大量的子文件夹.这是正常的,Go运行时甚至可以处理数十万个goroutine.

另请注意,性能瓶颈很可能是您的存储/硬盘速度,因此您可能无法获得所需的性能.在某一点(您的硬盘限制)之后,您将无法提高性能.

同时为每个子文件夹启动一个新的goroutine可能不是最佳选择,可能是通过限制文件夹中的goroutine数量来获得更好的性能.为此,请检查并使用工作池:

Is this an idiomatic worker thread pool in Go?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读