Search for subdirectories in C #

I have a list of file names and I want to find the directory and all its subdirectories. These directories contain about 200,000 files each. My code finds the file, but takes about 20 minutes per file. Can anyone suggest a better method?

Code snippet

String[] file_names = File.ReadAllLines(@"C:\file.txt");
foreach(string file_name in file_names) 
{
    string[] files = Directory.GetFiles(@"I:\pax\", file_name + ".txt",
                                        SearchOption.AllDirectories);
    foreach(string file in files)
    {
        System.IO.File.Copy(file, 
                            @"C:\" + 
                            textBox1.Text + @"\N\O\" + 
                            file_name + 
                            ".txt"
                            );
    }

}
+5
source share
7 answers

If you are looking for multiple files in the same directory structure, you should find all the files in this directory structure once, and then search them in memory. There is no need to access the file system again and again.

EDIT: There's an elegant way to do this, with LINQ - and a less elegant way, without. Here is the LINQ path:

using System;
using System.IO;
using System.Linq;

class Test
{
    static void Main()
    {
        // This creates a lookup from filename to the set of 
        // directories containing that file
        var textFiles = 
            Directory.GetFiles("I:\\pax", "*.txt", SearchOption.AllDirectories)
                     .ToLookup(file => Path.GetFileName(file),
                               file => Path.GetDirectoryName(file));

        string[] fileNames = File.ReadAllLines(@"c:\file.txt");
        // Remove the quotes for your real code :)
        string targetDirectory = "C:\\" + "textBox1.Text" + @"\\N\\O\\";

        foreach (string fileName in fileNames)
        {
            string tmp = fileName + ".txt";
            foreach (string directory in textFiles[tmp])
            {
                string source = Path.Combine(directory, tmp);
                string target = Path.Combine(targetDirectory, tmp);
                File.Copy(source, target);                                       
            }
        }
    }
}

, , LINQ. , , , - . , ? (, a.txt , "a" .)

+13

, , . Directory.GetFiles() HashSet<String>. HashSet. , . .

, , , . - .

:

String[] file_names = File.ReadAllLines(@"C;\file.txt");
HashSet<string> allFiles = new HashSet<string>();
string[] files = Directory.GetFiles(@"I:\pax\", file_name + ".txt", SearchOption.AllDirectories);
foreach (string file in files)
{
    allFiles.Add(file);
}

foreach(string file_name in file_names)
{
    String file = allFiles.FirstOrDefault(f => f == file_name);
    if (file != null)
    {
        System.IO.File.Copy(file, @"C:\" + textBox1.Text + @"\N\O\" + file_name + ".txt");
    }
}

, . , [].

+2

GetFiles() , , , .

.

, 1 file_name in file_names .

+1

- -, , , GetFiles() , , , ( ).

, - ;

+1

, API- .NET Windows... , ( , XP Windows).

Google

0

LINQ . 100% , .

var filesResult = from file in new DirectoryInfo(path).GetFiles("*.txt", SearchOption.AllDirectories)
                  where file.Name = filename
                  select file;

, , .

0

Linq , , . , , .

. , -, FileSystemListener . , Dictionary > lt; > HashSet < > . (, , Linq). , /add/delete/rename, . , .

If these are requests from a tool that caused a lot, you probably want to create a FileSystemWatcher in the service and connect to / request this service from a real tool that needs to know so that the file system information can be once, and is reused for the service life process.

0
source

All Articles