Recursive iteration in C# - c#

I have a custom object that contains methods that returns all directory and file names in a root
string[] dirlist = obj.GetDirectories();
//which returns all dir names in root
string[] filelist = obj.GetFiles();
//which return all file names in root
I cannot modify these methods. Once I get the dirlist, how do i get a list of all subdirs in it as well as files in the subdirs, ignoring the security exceptions. It can be nested to multiple levels. Anything in .NET 4?
Update: string[] dirList can also be read as List dirlist. Please give a solution that uses the latest features of .NET
DirectoryOne
- SubDirOne
- SubDirTwo
- FileOne
- FileTwo
- SubDirThree
DirectoryTwo
DirectoryOne

There are already built-in .NET methods to do this:
// get all files in folder and sub-folders
Directory.GetFiles(path, "*", SearchOption.AllDirectories);
// get all sub-directories
Directory.GetDirectories(path, "*", SearchOption.AllDirectories);
Somehow I get the feeling this isn't the solution you're looking for though.
Update:
I think I may know what you're trying to ask, since you tagged it as LINQ. If you want to get a list of all sub-directories and sub-folders given a list of directories, you can use the following code:
// get all files given a collection of directories as a string array
dirList.SelectMany(x => Directory.GetFiles(x, "*", SearchOption.AllDirectories));
// get all sub-directories given a collection of directories as a string array
dirList.SelectMany(x => x.Directory.GetDirectories(x, "*", SearchOption.AllDirectories));

Have a look at the Directory Class
foreach(string dir in Directory.GetDirectories("c:\","",SearchOption.AllDirectories))
{
Console.Writeline(dir);
foreach(string file in Directory.GetFiles(dir))
{
Console.Writline(file);
}
}
This will print all directories under C:\ and then all the files in each of those directories.
Does that help?

Related

C# List files in directory with wildcard on directory

I'm trying to list files on the directory using a wildcard in the directory name.
Something like:
var fileEntries = Directory.GetFiles("C:\\Users\\*\\Desktop\\statistics.txt");
When I'm trying to run this I get an exception about illegal characters.
I don't know what is the username on each PC in my network so it isn't possible to use regex (I think so).
So how can I search for files in a directory using the wildcard on the directory name?
Depending what you want to do with files inside wildcarded path, you can start with:
var dirs = Directory.GetDirectories("c:\\Users", "Desktop*", SearchOption.AllDirectories);
foreach (var d in dirs)
{
var files = Directory.GetFiles(d, "statistics.txt", SearchOption.AllDirectories);
}
One potential option is an overloaded method of Directory.GetFiles, here is documentation.
Using that method, your solution may looks something like:
Directory.GetFiles(
#"C:\Users",
"statistics.txt",
SearchOption.AllDirectories);
Note that SearchOption.AllDirectories will search all subdirectories of "C:\Users" folder. This may have a negative impact on performance, but if you are trying to return all files in a directory and subsequent subdirectories with a certain name, I think it is your best option.

C# Getting paths of all folders and subfolders, excluding folders with only other folders in them

I'm trying to obtain all of the folder paths that have files inside them, while excluding the folder paths that only have other folders in them. I'm using
Directory.GetDirectories(dirPath, "*", SearchOption.AllDirectories);
Which does what I need it to, except that it returns the paths of folders that only have other folders in them.
One way to do this would be to EnumerateFiles for the directory and all it's sub-directories, and get a Distinct() list of their directory names:
List<string> directoriesWithFiles = Directory
.EnumerateFiles(rootDir, "*", SearchOption.AllDirectories)
.Select(Path.GetDirectoryName)
.Distinct()
.ToList();
The first way I thought to do this was to use EnumerateDirectories, and then for each directory use EnumerateFiles to filter out directories that don't contain any files. But this turned out to be much slower than the method above:
List<string> directoriesWithFiles = Directory
.EnumerateDirectories(rootDir, "*", SearchOption.AllDirectories)
.Where(d => Directory.EnumerateFiles(d).Any())
.ToList();

C# get file paths of just files with no extensions

I am wanting to get a string array of paths of files that do not have extensions. They are binary files with no extensions if that helps.
For example, I am loading a group of file paths out of a folder /test/
I want just the path and filenames that do not have a extension (so no .txt, no .csv, no .*)
/test/dontWant.txt
/test/dontWant.csv
/test/doWant
if i do:
String[] paths = Directory.GetFiles(fDir, "*.*", SearchOption.AllDirectories);
I of course get everything in those directories.
if I then try:
String[] paths= Directory.GetFiles(fDir, "*", SearchOption.AllDirectories);
I will still get everything in that directory.
Is there a way to just get the files of those that have no extension?
using "*." did work, and I don't know why I didn't try that to start with.
I should have been using EnumerateFiles to start with.
You can try with this wildcard
String[] paths = Directory.GetFiles(fDir, "*.", SearchOption.AllDirectories);
also you can use this wildcard with Directory.EnumerateFiles
Directory.EnumerateFiles(fDir, "*.", SearchOption.AllDirectories);
This will help:
var filesWithoutExtension = System.IO.Directory.GetFiles(#"D:\temp\").Where(filPath => String.IsNullOrEmpty(System.IO.Path.GetExtension(filPath)));
foreach(string path in filesWithoutExtension)
{
Console.WriteLine(path);
}
It will return all the files w/o extension only in specified dir. If you want to include all the sub-directories you'd have to use: System.IO.Directory.GetFiles(#"D:\temp\", "*", SearchOption.AllDirectories).
UPDATE
As guys suggested, it's better to use Directory.EnumerateFiles because it consumes less ram.
You will need to do a 2nd pass filter on it.
//If you are using .NET 3.5 you can still use GetFiles, EnumerateFiles will just use less ram.
String[] paths = Directory.EnumerateFiles(fDir, "*.*", SearchOption.AllDirectories)
.Where(file => Path.GetFileName(file) == Path.GetFileNameWithoutExtension(file))
.ToArray();
So what this does is it passes your file path to GetFileName and GetFileNameWithoutExtension, if both of those return the same string it then includes the result in the array.
As an alternative to aleksey.berezan's answer, you can do the following in .NET 4+. EnumerateFiles will return files as they are traversed in the directory tree.
foreach(var file in Directory.EnumerateFiles(fDir, "*.*", SearchOption.AllDirectories).Where(s => string.IsNullOrEmpty(Path.GetExtension(s))))
{
}

How to iterate through the physical folders and read a leaf file in C#

I have a root node A which contains B which contains C which contains D which contains an XML file abc.xml
So in D:\ drive ,I have the following structure of directories A>>B>>C>>D.
This path is dynamic. What is the best practice to read the file abc.xml in C# by iterating through the physical folders?
You could implement a recursive search algorithm that goes through all the folders and descends into the sub folders.
Pseudo Code:
public void GetXMLFilesRecursive(string currentFolder, List<string> results)
{
// Enumerate all directories of currentFolder
string[] folders = Directory.GetDirectories(currentFolder);
foreach (string folder in folders)
GetXMLFilesRecursive(folder, results));
// Enumerate all XML files in this folder only if it has no other sub-folders (is a leaf)
if (folders.Length == 0)
{
string[] xmlFiles = Directory.GetFiles(currentFolder, "*.xml");
results.AddRange(xmlFiles);
}
}
This method only returns XML files in the lowest folders of the hierarchy (i.e. folders that don't have sub folders). If you want all files you find along the way, comment out if (folders.Length == 0). On the other hand, you could then also use Directory.GetFiles with SearchOption.AllDirectories.
Why I wrote a recursive algorithm: The OP asked how to find all XML files in the leaf directories. You can not do that using Directory.GetFiles with SearchOption.AllDirectories, but you then need to implement the above.
You can use Directory.GetFiles(d, "*.xml",SearchOption.AllDirectories) to get all the xml files get what you are looking for.
You can search an entire tree for a file using Directory.GetFiles(path,searchPattern,SearchOption) or Directory.EnumerateFiles with SearchOption.AllDirectories, eg
var fullPaths=Directory.GetFiles(myPath,"abc.xml",SearchOption.AllDirectories)
You can also use the DirectoryInfo class to get full FileInfo instances instead of just the paths, with access to file properties and attributes:
var myDir=new DirectoryInfo(myPath);
var fileInfos=myDir.GetFiles("abc.xml",SearchOption.AllDirectories);
The difference between the GetFiles and EnumerateFiles methods is that the first returns an array with all the files found, blocking until it finds all of them. EnumerateFiles on the other hand returns results as it finds them, so you get to process the results much sooner.
What goes for GetFiles goes for the GetDirectories/EnumerateDirectories set of functions as well. The methods are available both from the Directory and DirectoryInfo class.
If you want to search for both directories and files, you can use GetFileSystemEntries/EnumerateFileSystemEntries to return both of them with a single call. The equivalent DirectoryInfo methods are GetFileSystemInfos/EnumerateFileSystemInfos
public List<string> getFiles(string path, string searchPattern, List<string> list)
{
try
{
foreach (string folder in Directory.GetDirectories(path))
getFiles(folder, searchPattern, list);
list.AddRange(Directory.GetFiles(path, searchPattern));
}
catch (UnauthorizedAccessException)
{
//Do not have access to the file.
}
return list;
}
Call like this:
//Get all xml files in the D drive:
List<string> files = getFiles(#"d:\", "*.xml", new List<string>());

C# - List the name of each file in a directory into an Array?

How would one list the files in a directory into an Array? Files only, I could care less for folders. I know in python it's:
for file in os.listdir('Blah'):
#BlahBlahBlah
However, I'm not sure how I would go about doing so in C#.
Thank you for your help!
Use Directory.GetFiles method
string[] filesArray = Directory.GetFiles("yourpath");
Returns the names of files (including their paths) in the specified
directory.
Remember to include System.IO
You can also use Directory.GetFiles Method (String, String) to search files by specifying search patterns. Something like:
string[] fileArray = Directory.GetFiles(#"c:\", "X*");
return all files starting with Character X
You may use:
if(Directory.Exists("yourpath"))
to check if the path exists
using System.IO;
string[] files = Directory.GetFiles("PATH");
OR
string[] files = Directory.GetFiles("PATH","*.docx",SearchOption.AllDirectories);
OR
string[] files = Directory.GetFiles("PATH","*.pdf",SearchOption.TopDirectoryOnly);
OR
string[] files = Directory.GetFiles("PATH","*.xlsx");
Try following...Use System.IO directory
string[] filePaths = Directory.GetFiles(#"D:\MyDir\");

Categories