C
C#ā€¢2y ago
Drajzer

āœ… Searching for all possible files with .txt extension

How i can search for all .txt files on all drives ?
10 Replies
Drajzer
DrajzerOPā€¢2y ago
Or i can search on one drive and then do it for another one but how
Thinker
Thinkerā€¢2y ago
Directory.GetFiles("C:/", "*.txt", new EnumerationOptions() { RecurseSubdirectories = true })
Directory.GetFiles("C:/", "*.txt", new EnumerationOptions() { RecurseSubdirectories = true })
Although this is very likely to cause access violation exceptions and take a very long time
Drajzer
DrajzerOPā€¢2y ago
i have this
public List<string> Search()
{
var files = new List<string>();
foreach (DriveInfo d in DriveInfo.GetDrives().Where(x => x.IsReady))
{
try
{
files.AddRange(Directory.GetFiles(d.RootDirectory.FullName, "*.txt", SearchOption.AllDirectories));
}
catch(Exception e)
{
Logger.Log(e.Message); // Log it and move on
}
}

return files;
}
public List<string> Search()
{
var files = new List<string>();
foreach (DriveInfo d in DriveInfo.GetDrives().Where(x => x.IsReady))
{
try
{
files.AddRange(Directory.GetFiles(d.RootDirectory.FullName, "*.txt", SearchOption.AllDirectories));
}
catch(Exception e)
{
Logger.Log(e.Message); // Log it and move on
}
}

return files;
}
mtreit
mtreitā€¢2y ago
You are almost certainly going to hit an access denied exception on at least some path somewhere on the drive so I don't think that code is going to work.
Drajzer
DrajzerOPā€¢2y ago
it wont i need help idk i can try catch but idk
mtreit
mtreitā€¢2y ago
Here is a sketch of how I might approach it:
if (args.Length < 2)
{
Console.WriteLine("Usage:");
Console.WriteLine("Program.exe <rootPath> <searchPattern>");
return;
}

var files = FindFiles(args[0], args[1]);

foreach (var file in files)
{
Console.WriteLine(file);
}

IEnumerable<string> FindFiles(string rootPath, string searchPattern)
{
var queue = new Queue<string>();
queue.Enqueue(rootPath);

while (queue.Count > 0)
{
var current = queue.Dequeue();

try
{
foreach (var dir in Directory.EnumerateDirectories(current))
{
queue.Enqueue(dir);
}
}
catch (Exception e)
{
Console.WriteLine($"Skipping {current} due to error: {e.Message}.");
continue;
}

foreach (var file in Directory.EnumerateFiles(current, searchPattern))
{
yield return file;
}
}
}
if (args.Length < 2)
{
Console.WriteLine("Usage:");
Console.WriteLine("Program.exe <rootPath> <searchPattern>");
return;
}

var files = FindFiles(args[0], args[1]);

foreach (var file in files)
{
Console.WriteLine(file);
}

IEnumerable<string> FindFiles(string rootPath, string searchPattern)
{
var queue = new Queue<string>();
queue.Enqueue(rootPath);

while (queue.Count > 0)
{
var current = queue.Dequeue();

try
{
foreach (var dir in Directory.EnumerateDirectories(current))
{
queue.Enqueue(dir);
}
}
catch (Exception e)
{
Console.WriteLine($"Skipping {current} due to error: {e.Message}.");
continue;
}

foreach (var file in Directory.EnumerateFiles(current, searchPattern))
{
yield return file;
}
}
}
Probably want a try-catch around the EnumerateFiles call as well, exercise left to the reader.
canton7
canton7ā€¢2y ago
Any reason to go breadth-first rather than depth-first? That feels like it'll end up adding lots of dirs to the queue, while the max folder depth doesn't tend to be that large
mtreit
mtreitā€¢2y ago
Not really, just what I did off the top of my head
if (args.Length < 2)
{
Console.WriteLine("Usage:");
Console.WriteLine("Program.exe <rootPath> <searchPattern>");
return;
}

var files = FindFiles(args[0], args[1]);

foreach (var file in files)
{
Console.WriteLine(file);
}

IEnumerable<string> FindFiles(string rootPath, string searchPattern)
{
var stack = new Stack<string>();
stack.Push(rootPath);

while (stack.Count > 0)
{
var current = stack.Pop();

try
{
foreach (var dir in Directory.EnumerateDirectories(current))
{
stack.Push(dir);
}
}
catch (Exception e)
{
Console.WriteLine($"Skipping {current} due to error: {e.Message}.");
continue;
}

foreach (var file in Directory.EnumerateFiles(current, searchPattern))
{
yield return file;
}
}
}
if (args.Length < 2)
{
Console.WriteLine("Usage:");
Console.WriteLine("Program.exe <rootPath> <searchPattern>");
return;
}

var files = FindFiles(args[0], args[1]);

foreach (var file in files)
{
Console.WriteLine(file);
}

IEnumerable<string> FindFiles(string rootPath, string searchPattern)
{
var stack = new Stack<string>();
stack.Push(rootPath);

while (stack.Count > 0)
{
var current = stack.Pop();

try
{
foreach (var dir in Directory.EnumerateDirectories(current))
{
stack.Push(dir);
}
}
catch (Exception e)
{
Console.WriteLine($"Skipping {current} due to error: {e.Message}.");
continue;
}

foreach (var file in Directory.EnumerateFiles(current, searchPattern))
{
yield return file;
}
}
}
There šŸ™‚ Alternate version I guess you would want to call Reverse() on Directory.EnumerateDirectories() if you want the same order you would get if you did something like Get-ChildItem -Recurse (i.e., dir /s)
Drajzer
DrajzerOPā€¢2y ago
thank you lot of ā¤ļø but i cant access Desktop and Documents,i can access if im going first in directory and list files then get files name but with that code i cant im running .exe as admin
DirectoryInfo place = new DirectoryInfo(@"C:\Users\*****\Desktop");
FileInfo[] fls = place.GetFiles();
Console.WriteLine("DESKTOP: ");
foreach(FileInfo i in fls)
{
Console.WriteLine(i.Name);
}
DirectoryInfo place = new DirectoryInfo(@"C:\Users\*****\Desktop");
FileInfo[] fls = place.GetFiles();
Console.WriteLine("DESKTOP: ");
foreach(FileInfo i in fls)
{
Console.WriteLine(i.Name);
}
like this i can create list return it but is there way to dont do like that and access it with ur code
Accord
Accordā€¢2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.

Did you find this page helpful?