I have a curious problem in a C#-program.
I have some local folderpaths like
"C:\test\AB_Systems\ELEGANCE\CB-DOC\live\M7-091.249.99.XX.01\extobjects".
Now i want to search for PDF-files in the subfolder called "extobjects".
Unfortunately there are many subfolders in the folder "live", which got a subfolder called "extobjects", so i thought it would be better to use a wildcard in the searchpath like that:
"C:\test\AB_Systems\ELEGANCE\CB-DOC\live\*\extobjects"
But this doesn't work.
Is there a way do do this?
public static FileInfo[] findFile(String whereToSearch, String searchFor , String mode)
{
IEnumerable<FileInfo> files = null;
if (mode.Equals(""))
mode = "s";
if (searchFor.Equals(""))
searchFor = "*";
if (mode.Equals("r") || mode.Equals("recursive"))
{
DirectoryInfo dir = new DirectoryInfo(whereToSearch);
files = dir.EnumerateFiles(searchFor, searchOption: SearchOption.AllDirectories);
}
if (mode.Equals("s") || mode.Equals("specific"))
{
DirectoryInfo dir = new DirectoryInfo(whereToSearch);
files = dir.EnumerateFiles(searchFor, searchOption: SearchOption.TopDirectoryOnly);
}
if (files != null) return files.ToArray<FileInfo>();
else return null;
}
That's an example how to do it.
It's important to say that only the filename can contain a wildcard pattern like *. The Path can be given as where to start the search and by giving searchOption: searchOption.AllDirectories as an argument it will go through all sub-directories of the entry path.
You will receive an Array of FileInfo which objects that contain the the path and more information.
You can use Linq like this:
var files = Directory
.EnumerateDirectories(#"C:\test\AB_Systems\ELEGANCE\CB-DOC\live", "extobjects", SearchOption.AllDirectories)
.SelectMany(x => Directory.EnumerateFiles(x, "*pdf", SearchOption.TopDirectoryOnly))
.ToArray();
I'd choose a solution exactly what BugFinder proposed, you could optimize the following foreach-loop into a LINQ query if your .NET target supports it.
// Itterate subdirectories of the live folder
foreach (var subDir in Directory.GetDirectories(#"C:\test\AB_Systems\ELEGANCE\CB-DOC\live"))
{
// Check if path to extobjects exists
var extObjects = Path.Combine(subDir, "extobjects");
if (Directory.Exists(extObjects))
{
var pdfFiles = Directory.GetFiles(extObjects, "*").Where(x=>x.EndsWith(".pdf"));
// Do something with the pdf file paths
}
}
Related
Suppose I forget the full path of a file on my computer, but I remember the filename and a segment of the path.
example:
my filename is test and the segment of the path that I sill remember is \test1\test2
So I would like to get the full path with c#, like this: C:\test1\test2\test3\test4\test.txt
Thanks in advance!
If the segment you know is at the start of the path, you can do something like
DirectoryInfo f = new DirectoryInfo(#"C:\test1\test2");
var results = f.GetFiles("test.txt", SearchOption.AllDirectories);
If not, I'm afraid that you have to do a full search on the computer, and check if the result path contains your fragment.
You can go through all the files on the drive and check whether they match what you want: (This will be slow and resource consuming.)
var files = Directory.GetFiles(#"C:\", "test.txt", SearchOption.AllDirectories)
.Where(s => s.Contains(#"\test1\test2\"));
foreach (var f in files)
{
Console.WriteLine(f);
}
Or you know the root directory in which you want to search, you can change it like this to be faster:
var files = Directory.GetFiles(#"C:\test1\test2", "test.txt", SearchOption.AllDirectories);
foreach (var f in files)
{
Console.WriteLine(f);
}
How to get list of Direct Directories named something-***** using C# in **D:\myfolder**
I tried
String root = #"E:\something-*";
var directories = Directory.GetDirectories(root);
but it is giving error infact, the listing of E:\ also results in null as value in variable directories.
I also tried looking for possible solutions on stackoverflow and other forums but did not get any appropriate answer to my query.
Here is an example that will compile an array of DirectoryInfo objects (directories) that match the SearchPatn that exists in the Path.
So, if Path equals "D:\myfolders\" and SearchPatn equals "something-*", You'll get results like: something-abc, something-xyz as folders that you can manipulate.
Caution with the searchOption: AllDirectories will search through all the folders below your path and return anything it finds. If you only want folders from your root, use the TopDirectoryOnly searchOption.
// this returns an array of folders based on the SearchPatn (i.e., the folders you're looking for)
private DirectoryInfo[] getSourceFolders(string Path, string SearchPatn)
{
System.IO.DirectoryInfo[] f = new DirectoryInfo(Path).GetDirectories(SearchPatn, searchOption: SearchOption.AllDirectories);
return f;
}
You need the overload of GetDirectories that takes a search pattern and prepare the correct pattern to search for
String root = #"E:\something-*";
string parent = Path.GetDirectoryName(root);
// A little trick, here GetFilename will return "something-*"
string search = Path.GetFileName(root);
var dirs = Directory.GetDirectories(parent, search);
There is also a third overload that allows you to search the pattern recursively under the parent folder
var dirs = Directory.GetDirectories(parent, search, SearchOption.AllDirectories);
The problem you are experiencing is caused by the presence of system directories like the System Volume Information on which you don't have permission to read its content. MSDN has an example how to overcome this situation and could be adapted to your requirements with some minor changes like the one here below
// Call the WalkDirectoryTree with the parameters below
// Notice that I have removed the * in the search pattern
var dirs = WalkDirectoryTree(#"E:\", #"something-");
List<string> WalkDirectoryTree(string root, string search)
{
try
{
var files = Directory.GetFiles(root, "*.*");
}
// This is thrown if even one of the files requires permissions greater
// than the application provides.
catch (UnauthorizedAccessException e)
{
// This code just writes out the message and continues to recurse.
// You may decide to do something different here. For example, you
// can try to elevate your privileges and access the file again.
Console.WriteLine(e.Message);
return new List<string>();
}
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine(e.Message);
return new List<string>();
}
// Now find all the subdirectories under this directory.
List<string> subDirs = new List<string>();
List<string> curDirs = Directory.GetDirectories(root).ToList();
foreach (string s in curDirs)
{
if(s.StartsWith(search))
subDirs.Add(s);
var result = WalkDirectoryTree(s, search);
subDirs.AddRange(result);
}
return subDirs;
}
I want to know which folder contains files which have a $ in their names.
But I will get duplicate folder names if I use this code:
string local = #"C:\test\";
string[] dirs = Directory.GetFiles(local, "*$*", SearchOption.AllDirectories);
foreach(string dir in dirs)
{
string a = Path.GetFileName(Path.GetDirectoryName(dir));
}
This is the content of the test folder:
C:\test\20170321\$123.txt
C:\test\20170321\2$4.txt
C:\test\20170322\567.txt
C:\test\20170322\abc.txt
should be get result only 1 20170321
This should do it:
string local = #"C:\test\";
string[] dirs = Directory.GetFiles(local, "*$*", SearchOption.AllDirectories);
List<string> singleDirNames = dirs.Select(x=> Path.GetDirectoryName(x)).Distinct().ToList();
Explanation: Select from all filenames the directory and take only the distinct values of it into a list
EDIT:
As I just realized, you don't want the entire path, so to get the result from your post you need to use the Path.GetFileName() (there should be another way, I am looking for it):
List<string> singleDirNames = dirs
.Select(x=> Path.GetFileName(Path.GetDirectoryName(x)))
.Distinct().ToList();
Found it. Here would be actually the direct way to access the containing folder inspired by this answer:
List<string> singleDirNames = dirs.Select(x=> new FileInfo(x).Directory.Name)
.Distinct().ToList();
I need to list all directories from a path. I need to get only last subdirectory path and not all paths.
i.e. for
pathbase/2016/01
I don't need pathbase/2016 but pathbase/2016/01
Now I'm using this code:
List<string> dirs = new List<string>(Directory.EnumerateDirectories(pathBase));
string[] entries = System.IO.Directory.GetDirectories(pathBase, "*",
SearchOption.AllDirectories);
var listDir = from dir
in entries
return listDir.ToList();
What type of filter can i use in Linq to exclude this directory?
Thanks.
Do you mean you need all leafs directories (directories that don't have subdirectories)?
If so this should do it
// First off, don't use GetDirectories on the static Directory class, it returns a string path and not a DirectoryInfo which isn't very usefull here, instead create a DirectoryInfo and go from there:
var RootDirectory = new DirectoryInfo(pathBase);
// Then queries all of it's subdirectories and filter on those
var listDir = RootDirectory.GetDirectories("*",SearchOption.AllDirectories)
.Where(dir=>!dir.GetDirectories().Any())
.ToList();
I would like to be able to iterate through the name of some image files in a folder using c#. So for intance I have a folder named image and contains the following images
image
dog.jpg
cat.jpg
horse.jpg
I want to be able to go through the names and be able to say
if(filename == dog.jpg)
return true
else
return false
Something of that nature
Thank you
You should use the static Exists method on System.IO.File.
return System.IO.File.Exists("dog.jpg")
Since the method returns a boolean, there is no need for the if statement in the example you gave.
You can also use a bit of Linq magic to determine if a file exists in a folder structure, like this:
var dir = new System.IO.DirectoryInfo(startFolder);
var fileList = dir.GetFiles("*.*", System.IO.SearchOption.AllDirectories);
bool fileExists = fileList.Any(f => f.FullName == "dog.jpg");
or even shorter:
return System.IO.Directory
.GetFiles(#"c:\myfolder", "dog.jpg", SearchOption.AllDirectories)
.Any();
which would search the folder specified and all subfolder with the pattern "dog.jpg". The Any() extension method simply checks whether the IEnumerable contains any items. I think this is the most efficient way of doing this (based on gut feeling).
From http://weblogs.asp.net/israelio/archive/2004/06/23/162913.aspx Just insert your if in the "// do something with filename" area:
// How much deep to scan. (of course you can also pass it to the method)
const int HowDeepToScan=4;
public static void ProcessDir(string sourceDir, int recursionLvl)
{
if (recursionLvl<=HowDeepToScan)
{
// Process the list of files found in the directory.
string [] fileEntries = Directory.GetFiles(sourceDir);
foreach(string fileName in fileEntries)
{
// do something with fileName
Console.WriteLine(fileName);
}
// Recurse into subdirectories of this directory.
string [] subdirEntries = Directory.GetDirectories(sourceDir);
foreach(string subdir in subdirEntries)
// Do not iterate through reparse points
if ((File.GetAttributes(subdir) &
FileAttributes.ReparsePoint) !=
FileAttributes.ReparsePoint)
ProcessDir(subdir,recursionLvl+1);
}
}
get all the files
string[] filePaths = Directory.GetFiles(#"c:\yourfolder\");
and iterate through it
use Directory.GetFiles()
foreach(var file in (myDir.GetFiles("*.jpg")
{
if(file.Name == "dog.jpg") return true;
}
var files = System.IO.Directory.GetFiles("directory", "*.jpg");
foreach (var item in files)
{
if (System.IO.Path.GetFileName(item) == "dog.jpg")
{
// File found.
}
}
DirectoryInfo di = new DirectoryInfo("c:\\Images");
var files = di.GetFiles("*.jpg");
foreach (var fileInfo in files)
{
if (fileInfo.Name == "dog.jpg")
return true;
}
return false;