多线程使用好, 应该是一个不错的方式
C#有现成的函数, 微软的实现应该可以的, 肯定比自己实现的要高
首先你要将你这个文件夹设置为 允许索引服务索引,在文件夹属性中可以设置。
然后才是遍历,你可以先用C# 类库的 IO.Directory.GetFiles 来获取某个文件夹下所有的文件,看获取时CPU是否达到或接近100%,如果已经接近100%,那么用多线程也无法提高多少效率,如果不是这样,你可以考虑用多线程技术来实现。
我觉得多线程的提升效率非常有限,因为仅仅是获取目录/文件列表的话,并没有多少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
我也关注这个。。。
IO资源属于独占资源吧,多线程提高不了性能,瓶颈在于硬盘速度,如果用多线程,会造成线程间的一些问题:互斥、死锁等,建议不要用多线程;
可以用递归,简单易用,如果真想开发高效率的搜索系统,用文件驱动或者文件编制索引。
一个递归的例子,可以定义搜索深度。
Code
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)起新线程。但线程总数肯定是要控制的!楼上大侠提到硬盘速度,我觉得有理,不过不妨一试。
递归遍历~!