go – 并发文件系统扫描
我想获取目录中文件的文件信息(文件名和大小,以字节为单位).但是有很多子目录(~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仍然在后台工作,因为您可以使用 这是一个简单的实现: 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? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- java – 使用Apache HttpComponents客户端签署AWS HTTP请求
- java – 在两点之间画一条线
- java-ee – SecurityContext不适用于@RolesAllowed
- Java设计模式之建造者模式实例详解
- JAVA实现基于Tcp协议的简单Socket通信实例
- java – 将JScrollPane添加到显示图像的面板
- 为什么我收到java.lang.AbstractMethodError错误?
- java – 如何使用Hibernate尽快插入数据
- java – 使用齐射进行网络操作时如何显示ProgressDialog
- java – 使用content-disposition下载文件时出现问题