I was wondering if there was a way to only retrieve the directories that have certain extensions.
For example
List<string> directories = Directory.GetDirectories(sourceTextBox.Text, "*", SearchOption.AllDirectories).ToList();
would give me all of the directories and subdirectories inside the path I gave it. However I only want it to retrieve the directories that have a .jpg or .png file inside of them.
List<string> directories = Directory.GetDirectories(sourceTextBox.Text, "*.png", SearchOption.AllDirectories).ToList();
directories.addRange(Directory.GetDirectories(sourceTextBox.Text, "*.jpg", SearchOption.AllDirectories).ToList());
Any way I could do this?
No guarantees in terms of performance, but for each directory you could check its files to see if it contains any with the matching extension:
List<string> imageDirectories = Directory.GetDirectories(sourceTextBox.Text, "*", SearchOption.AllDirectories)
.Where(d => Directory.EnumerateFiles(d)
.Select(Path.GetExtension)
.Where(ext => ext == ".png" || ext == ".jpg")
.Any())
.ToList();
There is no built in way of doing it, You can try something like this
var directories = Directory
.GetDirectories(path, "*", SearchOption.AllDirectories)
.Where(x=> Directory.EnumerateFiles(x, "*.jpg").Any() || Directory.EnumerateFiles(x, "*.png").Any())
.ToList();
You can use Directory.EnumerateFiles method to get the file matching criteria and then you can get their Path minus file name using Path.GetDirectoryName and add it to the HashSet. HashSet would only keep the unique entries.
HashSet<string> directories = new HashSet<string>();
foreach(var file in Directory.EnumerateFiles(sourceTextBox.Text,
"*.png",
SearchOption.AllDirectories))
{
directories.Add(Path.GetDirectoryName(file));
}
For checking multiple file extensions you have to enumerate all files and then check for extension for each file like:
HashSet<string> directories = new HashSet<string>();
string[] allowableExtension = new [] {"jpg", "png"};
foreach(var file in Directory.EnumerateFiles(sourceTextBox.Text,
"*",
SearchOption.AllDirectories))
{
string extension = Path.GetExtension(file);
if (allowableExtension.Contains(extension))
{
directories.Add(Path.GetDirectoryName(file));
}
}
Related
I have this method that searches all files and folders in "C:\Sharing".
string[] fileArray = Directory.GetFiles(#"C:\Sharing", "*.*", SearchOption.AllDirectories);
And foreach shows me full path of each file. Great. However, since these are in a directory called "Sharing", I want to check and add files that are like
C:\Sharing\Jerry2022\wedding.jpg (array: 'wedding.jpg', 'Jerry2022')
C:\Sharing\snapshot.jpg (array: 'snapshot.jpg')
C:\Sharing\Newsletter\cover-june.webp (array: 'cover-june.webp', 'Newsletter')
So as you can see, I want to add file and subdirectory name to a string array or List, doesnt matter. Excluding "Sharing".
How can I split the results? I know I can use Substring and LastIndexOf("\") + 1 and separate the ending '' but I'm not sure how to match up the filename with the subdir name too.
Any help is appreciated
You can use DirectoryInfo to get the information you want:
C#:
var directoryInfo = new DirectoryInfo(#"C:\Sharing");
if (directoryInfo.Exists)
{
foreach (var fileInfo in directoryInfo.GetFiles("*.*", SearchOption.AllDirectories))
{
var fileName = fileInfo.Name;
Console.WriteLine(fileName);
var directoryName = fileInfo.DirectoryName;
// you can use split to get the directory name array
Console.WriteLine(directoryName);
}
}
I found an other way, use Uri for this scenario:
C#:
string[] fileArray = Directory.GetFiles(#"C:\Sharing", "*.*", SearchOption.AllDirectories);
foreach (var s in fileArray)
{
var uri = new Uri(s);
var uriSegments = uri.Segments.ToArray();
}
You will see each part of the full path, but you may need to use .Trim('/') for each part. Then you can use string.Equals to get directories which you want.
You could split the results using Split
But of course you can also work with FileInfo instead
I want to write foreach loop to get all files with specified extention from external txt file. For example I have in file variable:
extensions = "jpg,tif,bmp,png" or
extensions "jpg,tif" and I want to only get this files.
So far I have something like this but I don`t know how to go on.
extensions = Extensions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string sourceFile in Directory.GetFiles(SourcePath, "*.*", SearchOption.AllDirectories).Where(s => s.EndsWith(extensions.)))
{
}
I don`t know how to get to every element in 'extensions' array. How can I solved that?
You can use Enumerable.Contains and System.IO.Path.GetExtension:
string[] extensions = {".jpg",".tif",".bmp",".png" };
var files = Directory.EnumerateFiles(SourcePath, "*.*", SearchOption.AllDirectories)
.Where(s => extensions.Contains(Path.GetExtension(s), StringComparer.InvariantCultureIgnoreCase));
I need to get a list of all ReadOnly files under a directory including files under sub-folders. Is there something in the .NET Framework which would make this easier than looping through all the files?
var path = #"C:\";//Some path
var readOnlyFiles = new DirectoryInfo(path)
.EnumerateFiles("*", SearchOption.AllDirectories)
.Where(file => file.Attributes.HasFlag(FileAttributes.ReadOnly));
There's a flag in SearchOption.AllDirectories in System.IO.Directory.EnumerateFiles, which means a recursive search. Here's a way to do the stuff:
var readOnlyFiles =
Directory.EnumerateFiles("base directory", "*", SearchOption.AllDirectories)
.Where(file => new FileInfo(file).IsReadOnly).ToList();
I am trying to get .mp3 files from multiple folders.
I can already do it for one folder through this query :
this.MusicList.ItemsSource =
from string fileName in Directory.GetFiles(#"C:\Users\Public\Music\Sample Music")
where System.IO.Path.GetExtension(fileName) == ".mp3"
select new FileInfo(fileName);
Is there any other way to do it for a list of directories ?
Here is what I have tried so far (returns no results):
var paths = new Dictionary<string, string> {
{"default_music", #"C:\Users\Public\Music\Sample Music"},
{"alternative_folder", #"C:\tmp"}
};
this.MusicList.ItemsSource =
from string fileName in (from string directoryName in paths.Values select Directory.GetFiles(directoryName))
where System.IO.Path.GetExtension(fileName) == ".mp3"
select new FileInfo(fileName);
from string directoryName in paths.Values select Directory.GetFiles(directoryName); returns a {System.Linq.Enumerable.WhereSelectEnumerableIterator<string,string[]>} with my paths in its source field and its Result View contains of my .mp3 files.
Thank you
Try the following
this.MusicList.ItemsSource =
from path in paths
from fileName in Directory.GetFiles(path)
where System.IO.Path.GetExtension(fileName) == ".mp3"
select new FileInfo(fileName);
Strict method call version
this.MusicList.ItemSource = paths
.SelectMany(path => Directory.GetFiles(path))
.Where(fileName => System.IO.Path.GetExtension(fileName) == ".mp3")
.Select(fileName => new FileInfo(fileName));
You can use DirectoryInfo.EnumerateFiles method which accepts search pattern. Thus you don't need to get all files and filter them via calls to Path.GetExtension
var paths = new Dictionary<string, string> {
{"default_music", #"C:\Users\Public\Music\Sample Music"},
{"alternative_folder", #"C:\tmp"}
};
MusicList.ItemsSource = paths.Values.Select(p => new DirectoryInfo(p))
.SelectMany(d => d.EnumerateFiles("*.mp3"));
Also DirectoryInfo.EnumerateFiles returns FileInfo instances, which is also what you want.
Try this
Directory.EnumerateFiles(#"C:\Users\Public\Music\Sample Music", "*.mp3", SearchOption.AllDirectories)
to return an enumerable list of .mp3's, which you can further filter or enumerate etc. This is more efficient than GetFiles() for large numbers of files and/or directories.
http://msdn.microsoft.com/en-us/library/dd383571.aspx
Alternate to the esteemable JaredPar that tracks if it's a File/Directory:
var basePath = #"c:\temp";
var query =
from entry in Directory.EnumerateFileSystemEntries(basePath, "*.*", SearchOption.AllDirectories)
let isDirectory = Directory.Exists(entry)
let isFile = File.Exists(entry)
select new { isDirectory, isFile, entry};
query.Dump();
EDIT: Doh - misread question, missed the "from a set of directories" part; my shame is immeasurable. :)
I have the following piece of code:
string root = Path.GetDirectoryName(Application.ExecutablePath);
List<string> FullFileList = Directory.GetFiles(root, "*.*",
SearchOption.AllDirectories).Where(name =>
{
return !(name.EndsWith("dmp") || name.EndsWith("jpg"));
}).ToList();
Now this works very well, however the file names with it are quire long.
is there a way i can take out the path till root? but still show all the subfolders?
Root = C:\Users\\Desktop\Test\
But the code would return the whole path from C:
while I'd prefer if I could take out the root bit straight away. but still keep the file structure after it.
eg
C:\Users\\Desktop\Test\hi\hello\files.txt
would return
\hi\hello\files.txt
I know i can just iterate over the file list generated and remove it all one by one, I'm wondering if I can just filter it out stright.
Using the power of LINQ:
string root = Path.GetDirectoryName(Application.ExecutablePath);
List<string> FullFileList = Directory.GetFiles(root, "*.*", SearchOption.AllDirectories)
.Where(name =>
{
return !(name.EndsWith("dmp") || name.EndsWith("jpg"));
})
.Select(file => file.Replace(root, "")
.ToList();