Searching All Directories with SearchOption.AllDirectories - c#

this is my code below. I've already created a filter that searches for any all image file extensions but when my code runs the SearchOption.AllDirectories appears to be trying to open a particular path instead of searching all my directories.
Anyone help me on where I've gone wrong here?
string[] filters = { "*.jpg", "*.jpeg", "*.png", "*.gif", "*.bmp" };
var directory = new DirectoryInfo(lblText.Text);
var files = new List<FileInfo>();
foreach (var filter in filters)
{
var results = directory.GetFiles(filter, SearchOption.AllDirectories);
files.AddRange(results);
}
Thanks for any help! :)

I assume directory is a DirectoryInfo object and you're using this overload of GetFiles. Then a FileInfo[] is returned from the current directory matching the given search pattern and searching all subdirectories.
So the directory-path of the DirectoryInfo is the root directory.
For example:
DirectoryInfo imageDir = new DirectoryInfo(#"c:\Images");
FileInfo[] allJPGImages = imageDir.GetFiles(".jpg", SearchOption.AllDirectories);
Edit according to your edit.
So the particular path is the Text entered/shown in lblText. Another way to get all files with these extensions:
string[] filters = { "*.jpg", "*.jpeg", "*.png", "*.gif", "*.bmp" };
List<FileInfo> files = filters
.SelectMany(filter => directory.EnumerateFiles(filter, System.IO.SearchOption.AllDirectories))
.ToList();
which does not need to load all files into memory until it starts processing. when you are working with many files and directories, EnumerateFiles can be more efficient.

I am not sure what filter is in your code, but here is a simple example to search a directory.
string path = "C:\\myFolder1\\myFolder2";
DirectoryInfo dir = new DirectoryInfo(path);
FileInfo[] files;
files = dir.GetFiles("*.*", SearchOption.AllDirectories);
Maybe your path is wrong?
But the AllDirectories options begins at your specified path.

Related

Accessing files within child directories

I am trying to access the files in the images directory that lies within another directory but when I run my code it doesn't print out anything:
string path = #"C:\Path";
DirectoryInfo DFolder = new DirectoryInfo(path);
Collection cDetails = new Collection(DFolder);
string DFPath = DFolder.Name;
DirectoryInfo imDetails = new DirectoryInfo(imPath);
// Get Desired Directories
List<string> directoryFilter = new List<string> {"images", "videos", "RAW"};
List<DirectoryInfo> directoryList = DFolder
.GetDirectories("*", SearchOption.AllDirectories)
.Where(x => directoryFilter.Contains(x.Name.ToLower()))
.ToList();
string dpath = directoryList.ToString();
foreach (DirectoryInfo record in directoryList)
{
foreach (FileInfo file in record.GetFiles(#"*", SearchOption.TopDirectoryOnly))
{
Console.WriteLine(file); //It compiles but doesn't print anything on the console
}
}
Note: This isn't really an answer, so I'll delete it shortly, but wanted to give some sample code to test with in case it helps.
Your code works fine for me, so it seems that the problem is that either the directories don't exist, or they don't contain any files.
Here's a test program you can run which creates a bunch of directories under c:\temp, some of which have the names we care about. The names we care about are also found at different levels of depth in the path, yet they are all discovered:
static void CreateTestPathsAndFiles()
{
// Paths to create for testing. We will put a file in each directory below,
// but our search code should only print the file paths of those files that
// are directly contained in one of our specially-named folders
var testPaths = new List<string>
{
#"c:\temp\dummy1",
#"c:\temp\dummy1\raw", // This should print
#"c:\temp\dummy2",
#"c:\temp\dummy2\extra",
#"c:\temp\dummy3",
#"c:\temp\dummy3\dummy31",
#"c:\temp\dummy3\dummy32\raw", // This should print
#"c:\temp\extra",
#"c:\temp\images", // This should print
#"c:\temp\notUsed",
#"c:\temp\notUsed\videos", // This should print
#"c:\temp\raw", // This should print
#"c:\temp\videos\dummy1",
};
// Just something to make a unique file name
int fileId = 0;
// for testing, ensure that the directories exist and contain some files
foreach(var testPath in testPaths)
{
// Create the directory
Directory.CreateDirectory(testPath);
// Add a file to it
File.CreateText(Path.Combine(testPath, $"TempFile{fileId}.txt"))
.Write($"Dummy text in file {fileId}");
// Increment our file counter
fileId++;
}
}
static void Main(string[] args)
{
// Create our paths and files for testing
CreateTestPathsAndFiles();
// Now set our root directory, search for all folders matching our
// special folder names, and print out the files contained in them
var path = #"C:\Temp";
var directoryFilter = new List<string> {"images", "videos", "raw"};
// Get ALL sub-directories under 'path' whose name is in directoryFilter
var subDirectories = new DirectoryInfo(path)
.GetDirectories("*", SearchOption.AllDirectories)
.Where(x => directoryFilter.Contains(x.Name.ToLower()));
foreach (DirectoryInfo subDir in subDirectories)
{
foreach (FileInfo file in subDir.GetFiles(#"*", SearchOption.TopDirectoryOnly))
{
// We're using the FullName so we see the whole file path in the output
Console.WriteLine(file.FullName);
}
}
GetKeyFromUser("\nDone! Press any key to exit...");
}
Output
Note that the 5 files we expected to find are listed, but no others:
foreach (FileInfo file in record.GetFiles(#"*", SearchOption.TopDirectoryOnly))
{
Console.WriteLine(file); //It compiles but doesn't print anything on the console
}
SearchOption.TopDirectoryOnly will only search files in C://Path/images but not its subfolders.
a possible fix for this is to simply change your 2nd foreach loop to look like this:
foreach (FileInfo file in record.GetFiles(#"*", SearchOption.AllDirectories))
{
Console.WriteLine(file); //It compiles but doesn't print anything on the console
}
Edit:
Using SearchOption.AllDirectories as parameter is supposed to catch all cases of subfolders within your subfolder e.g. something like C://images//dir//somefile.txt instead of only taking the files within the topdirectory(in this case C://images). Which is(as i understood your question) exactly the kind of behaviour you were looking for.
Full code:
{
static void Main(string[] args)
{
// Directory Info
string path = #"C:\Path";
DirectoryInfo DFolder = new DirectoryInfo(path);
string DFPath = DFolder.Name;
// Get Desired Directories
List<string> directoryFilter = new List<string> { "images", "videos", "raw" };
List<DirectoryInfo> directoryList = DFolder.GetDirectories("*", SearchOption.AllDirectories).Where(x => directoryFilter.Contains(x.Name.ToLower())).ToList();
string dpath = directoryList.ToString();
foreach (DirectoryInfo record in directoryList)
{
foreach (FileInfo file in record.GetFiles(#"*", SearchOption.AllDirectories)) //searches directory record and its subdirectories
{
Console.WriteLine(file);
}
}
}
Final Edit: Sample output given the following structure:
C://Path//images//images.somefile.txt
C://Path//images//temp//images.temp.somefile.txt
C://Path//raw//raw.somefile.txt
C://Path//vidoes//videos.somefile.txt

How to get approximate file path?

I have a list file path as follow:
C:\Data\Default.aspx
C:\Data\Global.asax
C:\Data\Web.config
C:\Data\bin\PerlsComWebProject1.dll
C:\Data\bin\PerlsComWebProject1.pdb
I have a method to get file from folder path, however I want to print result as below:
Data\Default
Data\Global
Data\Web.config
Data\bin\PerlsComWebProject1
Data\bin\PerlsComWebProject1
Call: GetFilePathWithOutExtention(#"C:\\Data");
My code is only return file without an extension.
void GetFilePathWithOutExtention(string path)
{
string[] paths = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
foreach(var path in paths)
{
Console.WriteLine(Path.GetFileNameWithoutExtension(path));
}
}
Update: Thanks for your comments. "C:\Data\" is only a sample, sorry so make you confused. Actual, I have a any folder, I want to search this folder, get approximate path: this folder...\filename with out extention.
Ex: I have a path as follow: D:\EHO\Phase1\Data\Document\text.txt,....when I call method: GetFilePathWithOutExtention("D:\EHO\Phase1"), I want to output: Phase1\Data\Document\text, or GetFilePathWithOutExtention("D:\EHO\Phase1\Data"), output: Data\Document\text.
Thanks.
I think what you're looking for is Uri.MakeRelativeUri
So you could do something like this:
var folder = new Uri(#"C:\Data");
var paths = System.IO.Directory.GetFiles(folder.LocalPath, "*.*", System.IO.SearchOption.AllDirectories);
foreach (var uri in paths.Select(p => new Uri(p)))
{
Console.WriteLine(folder.MakeRelativeUri(uri).ToString());
}
This prints
Data/Default.aspx
Data/Global.asax
Data/Web.config
Data/bin/PerlsComWebProject1.dll
Data/bin/PerlsComWebProject1.pdb
A generic answer, valid for all folders inside the machine drives, not only 1st level:
void GetFilePathWithOutExtention(string path)
{
// Get the name of the folder containing your path (for further remove in the items folder)
string parentFolderName = Directory.GetParent(path).FullName;
string[] filePaths = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
foreach(string fileItemPath in filePaths)
{
// Get the current folder without the initial folder path
string currentItemPath = Path.GetDirectoryName(fileItemPath).Remove(0, parentFolderName.Length);
Console.WriteLine(Path.Combine(currentItemPath, Path.GetFileNameWithoutExtension(fileItemPath)));
}
}
you can just Show from the 4th char
void GetFilePathWithOutExtention(string path)
{
string[] filesName = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
foreach(var fileName in filesName)
{
string pathToWrite = Path.GetFileNameWithoutExtension(fileName);
if(pathToWrite != null && pathToWrite.length >3 )
Console.WriteLine(pathToWrite.Substring(3,pathToWrite.length);
}
}

quick and dirty way to recursively collect files from sub directories?

So I have a directory where a bunch of configuration files are stored, but now I also have several sub directories which also contain config files. I had a function for collecting all configuration files per station, but now it's only collecting files in the directory, not the sub folders. old code:
string MasterList = "ConfigsForStation1.txt";
string dirC = "..\\config\\Station1\\";
foreach (FileInfo fileC in dirC.GetFiles())
{
if(!System.IO.Path.GetExtension(fileC.FullName).EndsWith(".confg"))
{ WriteToList(fileC,MasterList);}
}
and now with this sub directory stuff implemented its more along these lines:
string MasterList = ...;
string dirC = ...;
//collect files in sub directories substations 1 & 2
foreach(DirectoryInfo Dx in dirC.GetDirectories())
{ foreach(FileInfo fileC in Dx.GetFiles())
{...}
}
//collect files in parent directory station 1
foreach(FileInfo fileC in dirC.GetFiles())
{...}
my question is: is there a cleaner way to collect files from all sub folders rather then nest a foreach inside of a foreach? and then do a third pass for the stuff in parent. It feels abit sloppy and I feel like theres some command like dirC.getAllsub() that will do so for me? just looking for hints and ideas to clean up the code.
There's Directory.EnumerateFiles() to which you can pass a parameter of SearchOption.AllDirectories which you can use to tell it to recurse the files for you automatically.
You should be able to do something like:
foreach (string filename in Directory.EnumerateFiles(dirC, "*.confg", SearchOption.AllDirectories))
... Do something with filename
Or if you need to process every file:
foreach (string filename in Directory.EnumerateFiles(dirC, "*", SearchOption.AllDirectories))
... Do something with filename
The GetFiles() method will return them all in one shot:
String dirC = "..\\config\\Station1\\";
DirectoryInfo di = new DirectoryInfo(dirC);
FileInfo[] fia = di.GetFiles("*.*", SearchOption.AllDirectories);
foreach (FileInfo fi in fia)
{
//do something with the file
}
You can replace the search pattern *.* with whatever fits the files you are looking for, such as *.cfg.
Use Directory.GetFiles() with SearchOption.AllDirectories. That will automatically recurse for you.
I wanted to write this as a comment but stackoverflow wasn't letting me.
Check out this question which provides many ways to do what you're asking.
use Directory.GetFiles:
var files = Directory.GetFiles("C:\\", "*", SearchOption.AllDirectories);

Directory is not reading properly

I am having One Directory
C:\Kuldeep\kverma\kver\
After that It consists thousands of Folders with Different name .Each Folder consists Different Excel File . I need to read Each Files from Different Folders .
I want To read All The Folders Path from C:\Kuldeep\kverma\kver\ Folder.
I used below code for getting the folders name with path ..
string path = #"C:\Kuldeep\kverma\kver\";
DirectoryInfo dir = new DirectoryInfo(path);
Console.WriteLine("File Name Size Creation Date and Time");
Console.WriteLine("========");
foreach (DirectoryInfo dirinfo in dir.GetDirectories())
{
String name = dirinfo.Name;
String pth = dirinfo.FullName;
Console.WriteLine( name, pth);
}
Total 10700 folders are there in C:\Kuldeep\kverma\kver\ Directory But It is reading only 54 Folder..
Please provide me any solution for Reading Folder name and location Also Reading File from Each Folder in Single Shot .
You should put a try catch around the GetDirectories call to handle the exceptions in the below post.
That might give you a clue as to why it is not enumerating properly.
http://msdn.microsoft.com/en-us/library/c1sez4sc.aspx
Try a recursive approach:
namespace ConsoleApplication1
{
using System;
using System.Collections.Generic;
using System.IO;
class Program
{
public static IList<DirectoryInfo> dirs;
static void Main(string[] args)
{
dirs = new List<DirectoryInfo>();
var dir = new DirectoryInfo(#"c:\tmp");
GetDirs(dir);
Console.WriteLine(dirs.Count);
}
public static void GetDirs(DirectoryInfo root)
{
foreach (var directoryInfo in root.GetDirectories())
{
dirs.Add(directoryInfo);
GetDirs(directoryInfo);
}
}
}
}
Now I'm not sure what hidden dangers might be lurking because of this (Stack overflow exceptions, access denied?) so I'd recommend placing a try..catch block in the foreach loop to help you out.
If you want to view the contents of every sub directory:
// Flatten out the directory structure in to a string array.
var directoryList = Directory.GetDirectories("<<RootPath>>", "*", SearchOption.AllDirectories);
foreach (var directory in directoryList)
{
DirectoryInfo info = new DirectoryInfo(directory);
}
edited with the questions code updated:
string path = #"C:\Kuldeep\kverma\kver\";
string[] directoryArray = Directory.GetDirectories(path, "*", SearchOption.AllDirectories);
foreach (var directory in directoryArray)
{
DirectoryInfo dirinfo = new DirectoryInfo(directory);
String name = dirinfo.Name;
String pth = dirinfo.FullName;
Console.WriteLine(name, pth);
}

Iterate through a root directory and get all files in it?

hi
i am creating a application and i want to know the each and every file which is present under that one folder .i.e. how can i iterate through a root directory and get the each files visit at list once.
If you just need to list them all at once, you can just use the overload for GetFiles that includes the option.
string[] filePaths = Directory.GetFiles(#"c:\MyDir\", "*.*", SearchOption.AllDirectories);
Obviously, in a web app you wouldn't likely have access to "c:\MyDir", so you can replace that with a variable holding the results of a MapPath call like so:
var rootDir = Server.MapPath("~/App_Data");
Use the Directory.EnumerateFiles(String, String, SearchOption) function with SearchOption.AllDirectories:
foreach (var file in Directory.EnumerateFiles(#"c:\", "*.txt", SearchOption.AllDirectories))
{
// Do stuff here
}
EnumerateFiles method is way faster than GetFiles method since it actually just returns the enumerator and does not actually access the files until they are red.
You can use the DirectoryInfo and FileInfo classes as well as a recursive function.
void Main()
{
DirectoryInfo info = new DirectoryInfo(#"C:\Personal");
ListContents(info);
}
public void ListContents(DirectoryInfo info)
{
foreach(var dir in info.GetDirectories())
{
ListContents(dir);
}
foreach(var file in info.GetFiles())
{
Console.WriteLine(file.FullName);
}
}

Categories