Reputation: 33
I wrote a program looking for a specific file in the computer, but it suffers from slow and delays in obtaining the many files on your computer
This function is working to get all the files
void Get_Files(DirectoryInfo D)
{
FileInfo[] Files;
try
{
Files = D.GetFiles("*.*");
foreach (FileInfo File_Name in Files)
listBox3.Items.Add(File_Name.FullName);
}
catch { }
DirectoryInfo[] Dirs;
try
{
Dirs = D.GetDirectories();
foreach (DirectoryInfo Dir in Dirs)
{
if (!(Dir.ToString().Equals("$RECYCLE.BIN")) && !(Dir.ToString().Equals("System Volume Information")))
Get_Files(Dir);
}
}
catch { }
}
Is there another way to get a little faster all the computer files??
Upvotes: 3
Views: 2438
Reputation: 6207
Use profiler to find out, what operation is the slowest. Then think about how to make it faster. Otherwise you can waste your time by optimizing something, that is not bottleneck and will not bring you expected speed up.
In your case, you will probably find, that when you call this function for the first time (when directory structure is not in cache), most time will be spent in GetDirectories() and GetFiles() functions. You can pre-cache list of all files in memory (or in database) and use FileSystemWatcher to monitor changes in filesystem to update your file list with new files. Or you can use existing services, such as Windows Indexing service, but these may not be available on every computer.
Second bottleneck could be adding files to ListBox. If number of added item is large, you can temporarily disable drawing of listbox using ListBox.BeginUpdate and when you finish, enable it again with ListBox.EndUpdate. This can sometimes lead to huge speed up.
Upvotes: 2
Reputation: 16802
You will find much faster performance using Directory.GetFiles()
as the FileInfo
and DirectoryInfo
classes get extra information from the file system which is much slower than simply than returning the string based file name.
Here is a code example that should yield much improved results and abstracts the action of retrieving files from the operation of displaying them in a list box.
static void Main(string[] args)
{
var fileFinder = new FileFinder(@"c:\SomePath");
listBox3.Items.Add(fileFinder.Files);
}
/// <summary>
/// SOLID: This class is responsible for recusing a directory to return the list of files, which are
/// not in an predefined set of folder exclusions.
/// </summary>
internal class FileFinder
{
private readonly string _rootPath;
private List<string> _fileNames;
private readonly IEnumerable<string> _doNotSearchFolders = new[] { "System Volume Information", "$RECYCLE.BIN" };
internal FileFinder(string rootPath)
{
_rootPath = rootPath;
}
internal IEnumerable<string> Files
{
get
{
if (_fileNames == null)
{
_fileNames = new List<string>();
GetFiles(_rootPath);
}
return _fileNames;
}
}
private void GetFiles(string path)
{
_fileNames.AddRange(Directory.GetFiles("*.*"));
foreach (var recursivePath in Directory.GetDirectories(path).Where(_doNotSearchFolders.Contains))
{
GetFiles(recursivePath);
}
}
}
Upvotes: 0
Reputation: 11216
Part of the problem is that the GetFiles method doesn't return until it has gotten all the files in the folder and if you are performing a recursive search, then for each sub folder you recurse into, it will take longer and longer.
Look into using DirectoryInfo.EnumerateFile or DirectoryInfo.EnumerateFileSystemInfos
From the docs:
The EnumerateFiles and GetFiles methods differ as follows: When you use EnumerateFiles, you can start enumerating the collection of FileInfo objects before the whole collection is returned; when you use GetFiles, you must wait for the whole array of FileInfo objects to be returned before you can access the array. Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient.
The same is true for EnumerateFileSystemInfos
You can also look into querying the Indexing Service (if it is installed and running). See this article on CodeProject:
http://www.codeproject.com/Articles/19540/Microsoft-Indexing-Service-How-To
I found this by Googling "How to query MS file system index"
Upvotes: 1
Reputation: 171178
You can enumerate all files once and store the list.
But if you can't do that, this is basically as good as it gets. You can do two small things:
Upvotes: 0
Reputation: 3951
The answer will generally depend on your operating system. In any case you will want to build and maintain your own database of files; explicit search like in your example will be too costly and slow.
A standard solution on Linux (and Mac OS X, if I'm not mistaken) is to maintain a locatedb file, which is updated by the system on a regular basis. If run on these systems, your program could make queries against this database.
Upvotes: 1