首页 新闻 会员 周边

求快速遍历文件夹下所有文件及文件夹算法,多线程应该是最好的吧?

0
悬赏园豆:200 [已关闭问题]

如题

Argo的主页 Argo | 初学一级 | 园豆:5
提问于:2009-07-28 20:38
< >
分享
其他回答(7)
0

多线程使用好, 应该是一个不错的方式

peterzb | 园豆:861 (小虾三级) | 2009-07-28 20:54
0

C#有现成的函数, 微软的实现应该可以的, 肯定比自己实现的要高

Wayne Gao | 园豆:260 (菜鸟二级) | 2009-07-28 22:18
0

首先你要将你这个文件夹设置为 允许索引服务索引,在文件夹属性中可以设置。

然后才是遍历,你可以先用C# 类库的 IO.Directory.GetFiles 来获取某个文件夹下所有的文件,看获取时CPU是否达到或接近100%,如果已经接近100%,那么用多线程也无法提高多少效率,如果不是这样,你可以考虑用多线程技术来实现。

eaglet | 园豆:17139 (专家六级) | 2009-07-29 08:03
0

我觉得多线程的提升效率非常有限,因为仅仅是获取目录/文件列表的话,并没有多少IO等待吧,递归遍历就足够了。

————————————————————

如果不递归,可以直接用.Net提供的方法直接获取所有文件,可能比自己递归更快:

 

foreach(string f in Directory.GetFiles(Dir, "*", SearchOption.AllDirectories))
{
……
}

 

获取所有子文件夹则使用类似的这个方法:Directory.GetDirectories (String, String, SearchOption)
————————————————————————————

经测试证实,直接使用Directory.GetFiles (String, String, SearchOption) 方法获取所有文件确实比以 Directory.GetFiles (String)方法递归更快:

测试代码:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
var path
= Console.ReadLine();
var s
= string.Empty;
change: Console.WriteLine(
"");
s
= Console.ReadLine();
var st
= DateTime.Now;
var x
= s == "a" ? all(path) : loop(path);
Console.Write(x
+ "个文件 - 耗时" + DateTime.Now.Subtract(st).TotalMilliseconds + "ms");
goto change;
}

static int loop(string p)
{
var x
= 0;
foreach (string f in Directory.GetFiles(p))
{
//Console.WriteLine(f);
x++;
}
foreach (string f in Directory.GetDirectories(p))
{
x
+= loop(f);
}
return x;
}

static int all(string p)
{
var x
= 0;
foreach (string f in Directory.GetFiles(p, "*", SearchOption.AllDirectories))
{
//Console.WriteLine(f);
x++;
}
return x;
}
}
}

 

测试结果:

这里可以看到,Directory.GetFiles (String, String, SearchOption) 方案比递归方案快100毫秒左右。

而如果将代码中的//Console.WriteLine(f);都去掉注释的话,Directory.GetFiles (String, String, SearchOption) 方案将比递归方案快1到3秒左右(大约为 11秒 VS 14秒),虽然不明白Console.WriteLine()为什么会放大这种时间差距,但提升还是很可观的。

 

补充:测试环境为 笔记本:CPU为Intel Core2 Duo(Merom) U7600(1.2G)  内存为2G 硬盘为东芝1.8寸HDD(4200转)操作系统为Windows 7 RC 7100

斯克迪亚 | 园豆:4124 (老鸟四级) | 2009-07-29 09:15
0

我也关注这个。。。

IS黑山老妖 | 园豆:550 (小虾三级) | 2009-07-29 11:40
0

IO资源属于独占资源吧,多线程提高不了性能,瓶颈在于硬盘速度,如果用多线程,会造成线程间的一些问题:互斥、死锁等,建议不要用多线程;

可以用递归,简单易用,如果真想开发高效率的搜索系统,用文件驱动或者文件编制索引。

一个递归的例子,可以定义搜索深度。

Code

winzheng | 园豆:8797 (大侠五级) | 2009-07-29 12:53
0
public List<string> GetFileNames(string path){
List
<string> result = new List<string>();
DirectoryInfo di
= new DirectoryInfo(path);
GetFileNamesRecursive(di,
ref result);
return result;
}

private void GetFileNamesRecursive(DirectoryInfo di, ref List<string> files){
result.AddRange(di.GetFileNames());
foreach(DirectoryInfo subDi in di.GetDirectoryInfos()){
GetFileNamesRecursive(subDi,
ref result);
}
}

当成伪代码看吧,具体函数名是不记得了,好在IDE会提示。

我早前遍历过,但肯定谈不上“快速”。如果要实现你所谓的多线程的话,应该是在遍历子文件夹时(函数 GetFileNamesRecursive)起新线程。但线程总数肯定是要控制的!楼上大侠提到硬盘速度,我觉得有理,不过不妨一试。

陛下 | 园豆:3938 (老鸟四级) | 2009-07-29 16:23
0

递归遍历~!

邢少 | 园豆:10926 (专家六级) | 2009-07-29 16:53
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册