I was wondering how I could use c# to find a specific file (example cheese.exe) within all possible directories? And then store the path to the directory it found it in?
This code fragment retrieves a list of all logical drives on the machine and then searches all folders on the drive for files that match the filename "Cheese.exe". Once the loop has completed, the List "files" contains the
var files = new List<string>();
//#Stan R. suggested an improvement to handle floppy drives...
//foreach (DriveInfo d in DriveInfo.GetDrives())
foreach (DriveInfo d in DriveInfo.GetDrives().Where(x => x.IsReady == true))
{
files.AddRange(Directory.GetFiles(d.RootDirectory.FullName, "Cheese.exe", SearchOption.AllDirectories));
}
If you want to know a little more about the mechanics of searching multiple directories, Googling revealed this post. It has a good solution and explanation of recursing through directories yourself. You can change the filespec in Directory.GetFiles to match your search string and probably use it as is.
The link is unfortunately dead now, but in a nutshell the solution basically boils down to:
string[] files = Directory.GetFiles("C:\\Starting\\Path\\For\\Search\\",
"cheese.exe",
SearchOption.AllDirectories);
Note the filespec (second parameter) accepts wildcards, so you can also search for ".exe" or even ".*" to list all files recursively.
Related
You know that in linux it's easy but I can't just understand how to do it in C# on Windows. I want to delete all files matching the wildcard f*.txt. How do I go about going that?
You can use the DirectoryInfo.EnumerateFiles function:
var dir = new DirectoryInfo(directoryPath);
foreach (var file in dir.EnumerateFiles("f*.txt")) {
file.Delete();
}
(Of course, you'll probably want to add error handling.)
I know this has already been answered and with a good answer, but there is an alternative in .NET 4.0 and higher. Use Directory.EnumerateFiles(), thus:
foreach (string f in Directory.EnumerateFiles(myDirectory,"f*.txt"))
{
File.Delete(f);
}
The disadvantage of DirectoryInfo.GetFiles() is that it returns a list of files - which 99.9% of the time is great. The disadvantage is if the folder contains tens of thousands of files (which is rare) then it becomes very slow and enumerating through the matching files is much faster.
You can use the Directory.GetFiles method with the wildcard overload. This will return all the filenames that match your pattern. You can then delete these files.
I appreciate this thread is a little old now, but if you want to use linq then
Directory.GetFiles("f:\\TestData", "*.zip", SearchOption.TopDirectoryOnly).ToList().ForEach(File.Delete);
I was wondering how I could use c# to find a specific file (example cheese.exe) within all possible directories? And then store the path to the directory it found it in?
This code fragment retrieves a list of all logical drives on the machine and then searches all folders on the drive for files that match the filename "Cheese.exe". Once the loop has completed, the List "files" contains the
var files = new List<string>();
//#Stan R. suggested an improvement to handle floppy drives...
//foreach (DriveInfo d in DriveInfo.GetDrives())
foreach (DriveInfo d in DriveInfo.GetDrives().Where(x => x.IsReady == true))
{
files.AddRange(Directory.GetFiles(d.RootDirectory.FullName, "Cheese.exe", SearchOption.AllDirectories));
}
If you want to know a little more about the mechanics of searching multiple directories, Googling revealed this post. It has a good solution and explanation of recursing through directories yourself. You can change the filespec in Directory.GetFiles to match your search string and probably use it as is.
The link is unfortunately dead now, but in a nutshell the solution basically boils down to:
string[] files = Directory.GetFiles("C:\\Starting\\Path\\For\\Search\\",
"cheese.exe",
SearchOption.AllDirectories);
Note the filespec (second parameter) accepts wildcards, so you can also search for ".exe" or even ".*" to list all files recursively.
Currently I am looping through my file system like this
For Each filename As String In Directory.GetFiles(sourceFolder, "*.doc")
However this is including docx files to the list of files that GetFiles returns. I wish to only search for doc files and not docx. Any idea if there is a truncate or stop search character I can use in the search pattern?
This is the default behaviour of GetFiles, you can use LINQ to do further filtering.
var files = Directory.GetFiles(#"C:\test", "*.doc")
.Where(file=> file.EndsWith(".doc", StringComparison.CurrentCultureIgnoreCase))
.ToArray();//If you want an array back
Directory.GetFiles Method (String, String)
When you use the asterisk wildcard character in a searchPattern such
as "*.txt", the number of characters in the specified extension
affects the search as follows:
If the specified extension is exactly three characters long, the method returns files with extensions that begin with the specified extension. For example, "*.xls" returns both "book.xls" and "book.xlsx".
Given the fact that you want to iterate over your files and considering the default behavior of these methods I suggest to use EnumerateFiles instead of GetFiles. In this way you could add a simple check on the extension of the current file
foreach(string filename in Directory.EnumerateFiles(sourceFolder, "*.doc"))
{
if(!filename.EndsWith("x", StringComparison.CurrentCultureIgnoreCase))
{
.....
}
}
Not elegant as the Linq only solution but still working and not creating an array of all the filenames present in the directory
I am not a C# programmer so may be there can be syntax mistake, but i think it may solve your problem.
foreach (FileInfo fi in di.GetFiles("*.doc")
.Where(fi => string.Compare(".doc", fi.Extension,
StringComparison.OrdinalIgnoreCase) == 0))
{
myFiles.Add(fi);
}
This question is similar:
Possible to specify directory path with a wildcard?
However in my case I want to obtain all files from every single folder named 'data' that is a first child of all folders in my directory.
Hypothetically what I would need is the following:
string[] files = System.IO.Directory.GetFiles(directory + "\\Share\\*\\data");
*'directory' is simply a string of the directory path
Wildcards are not accepted in both GetFiles and GetDirectories methods and it is my understanding, they must be used as filters as a second parameter (both these methods have that overload). However in the GetFiles case, it is specifically to filter files and not directories, and in the GetDirectories case, it is giving me the same error, as if the filter was only applicable on the lowest level directories (or something of the sort).
I could do this with multiple calls to GetDirectories and GetFiles in
a loop, but I'd rather find a more
elegant solution. (i.e. What I want to avoid:: Get all directories
under my directory\Share, loop through and add get all files for each
\data directory of those, agglomerate all of that into a list of
strings for my file names etc...)
EDIT - SOLUTION:: Actually #Steve Wong pointed me towards the solution I went with (hopefully regexes aren't a big no-no):
Regex reg = new Regex(#"^\\" + directory + #"\\Share\\.*\\data\\.*\.xml$");
List<string> files = System.IO.Directory.GetFiles(connect + "\\Share","*.*",SearchOption.AllDirectories).Where(path => reg.IsMatch(path)).ToList();
Thanks for the help!
You could try this:
string rootDirectory = directory + "\\Share\\";
var files = Directory.GetDirectories(rootDirectory, "*", SearchOption.AllDirectories).Where(
(directoryPath) => StringComparer.OrdinalIgnoreCase.Compare(Path.GetFileName(directoryPath), "Data") == 0).SelectMany(
(directoryPath) => Directory.GetFiles(directoryPath, "*"));
The Where clause will return all folder paths that end with a "Data/data" folder, and then the SelectMany returns all files in those folders.
I have a fairly unique situation. Did a lot of searching and most of what I'm seeing terminates at finding a particular file, using wildcards ("*.txt") as an example. What I need to do is move a file between paths, the first one having a changing subdirectory. I am downloading a .zip, extracting it, and moving a file who's name never changes. Its parent directory does change in name, based on a datestamp.
//original extracted folder
string path = #"C:\IP-Test_20140715\File.csv";
//where to move
string path2 = #"C:\File.csv";
File.csv will never change, yet IP-Test_20140715 will change based on the date (whatever the extracted folder is called), everything after the underscore will be different going forward.
If not possible to have wildcards in directories, is it possible to force the name of the extracted directory in c# using ZipFile.ExtractToDirectory?
Use:
Directory.EnumerateFiles (#"C:\IP-Test_20140715", "*.txt")
to enumerate over the different files.
Thus:
foreach(var subdir in Directory.EnumerateDirectories (#"C:\", "IP-Test_*")) {
foreach(var file in Directory.EnumerateFiles (subdir, "*.cvs")) {
File.Move(file,Path.Combine(#"C:\",Path.GetFileName(file)));
}
}
On the other hand, I don't see why you want to use C# for this? A simple bash script could do the trick way easier...