c# Directory.GetFiles file structure from app root - c#

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();

Related

Show list from last file to first save

I want to reverse the result displayed in a Combobox.
The last saved file would appear first, currently it is the opposite. it appears with this code:
string[] files = Directory.GetFiles(#"C:\Test\",*.TXT");
foreach (string file in files)
{
comboBox1.Items.Add(Path.GetFileNameWithoutExtension(file));
}
According to my research, the solution would be:
.OrderByDescending(p => p.CreationTime).ToArray();
added somewhere. But I don't know. Every attempt I've made has been unsuccessful.
Currently:
101-00.06.52.TXT
101-00.06.54.TXT
101-00.06.56.TXT
Desired outcome:
101-00.06.56.TXT
101-00.06.54.TXT
101-00.06.52.TXT
Does anyone know?
Instead of static method Directory.GetFiles() method, use GetFiles() method from DirectoryInfo class. Apply OrderByDescending() on it.
Directory.GetFiles():
Returns the names of files that meet specified
criteria
Vs
DirectoryInfo.GetFiles():
Returns a file list from the current directory.
Like,
DirectoryInfo di = new DirectoryInfo(#"C:\Test\"); //Get the Directory information
var allTxtFiles = di.GetFiles("*.txt") //Get all files based on search pattern
.OrderByDescending(p => p.CreationTime) //Sort by CreationTime
.Select(x => x.Name); //Select only name from FileInfo object
foreach (string file in allTxtFiles)
{
comboBox1.Items.Add(Path.GetFileNameWithoutExtension(file));
}
I don't know the reason why you problem. But if you want to receive correct result is simple. First try this:
string[] files = Directory.GetFiles(#"C:\Test\",*.TXT");
comboBox1.ItemsSource = files;
if the result is not correct. Use this:
string[] files = Directory.GetFiles(#"C:\Test\",*.TXT");
files = files.Reverse();
comboBox1.ItemsSource = files;

how to apply descending order according to creation time of the files [duplicate]

I am using Directory.GetFiles to get files from a particular folder.
By default files from that folder are coming sort by filename ie. in alphabetical order of filename. I want to get files in the order in which files are modified.
I cannot use Directory.GetInfo as I want to get the files which contain particular keyword.
Please let me know how can we get the file sorted by their modified date.
I am using the following code
string[] arr1 = Directory.GetFiles("D:/TestFolder", "*"Test12"*");
Any help would be greatly appreciated.
what about the below
DirectoryInfo di = new DirectoryInfo("D:\\TestFolder");
FileSystemInfo[] files = di.GetFileSystemInfos();
var orderedFiles = files.Where(f=>f.Name.StartsWith("Test12"))
.OrderBy(f => f.CreationTime)
.ToList();
you can replace f.Name.StartWith with any string function against your need (.Contains,etc)
you can replace f => f.CreationTime with f.LastWriteTime to get the modified time but bear in mind that starting in Windows Vista, last access time is not updated by default. This is to improve file system performance
if you change to directory info you could do
FileInfo[] files = new DirectoryInfo("path")
.GetFiles("filter")
.OrderBy(f => f.CreationTime)
.ToArray();
Edit:
Saw you wanted modified date, can do that with f.LastWriteTime instead
Try this way. It will work...
string path = "C:\\Users", FileName="YourFileName";
DirectoryInfo direct= new DirectoryInfo(path);
FileInfo[] files = direct.GetFiles();
Array.Sort(files , (x, y) => StringComparer.OrdinalIgnoreCase.Compare(x.CreationTime, y.CreationTime));
files = Array.FindAll(files , a => a.FullName.Contains(FileName) == true);
foreach(var file in files){
// do what you want..
Console.WriteLine(file.FullName);
}

LINQ IN where query

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));

How to get files from a specific sub-directories using c#?

I'm trying to get all *.html files which are inside sub-directories named abcd to an array.
The path given can contain multiple *.html files in multiple sub-directories and even in the root directory(i.e. immediately inside the user given path) but I only want those *.html files which are inside the specificly named sub-directories(abcd) using LINQ.
This is what I tried
string workingPath = #"D:\Testing";
string[] myFiles = workingPath.Select(dirs => Directory.GetDirectories(workingPath)
.Select(folders => (from item in Directory.GetDirectories(folders, "abcd", SearchOption.AllDirectories)
.Select(item => Directory.GetFiles(item, "*.html"))
)));
I'm getting an error
A query body must end with a select clause or a group clause (CS0742)
. How do I fix this?
Your code does not look like it will compile. To start with workingPath.Select will return a collection of chars and you are trying to iterate over that again , which does not make sense considering your requirements.
You need something like this
var files = new List<string>();
if (Directory.Exists(workingPath))
{
foreach (var f in Directory.GetDirectories(workingPath, "abcd",
SearchOption.AllDirectories))
{
files.AddRange(Directory.GetFiles(f, "*.html"));
}
}
You can also do a one liner using LINQ
var files2 = Directory.GetDirectories(workingPath, "abcd", SearchOption.AllDirectories)
.SelectMany(d => Directory.GetFiles(d, "*.html")).ToArray();

LINQ nested list comprehension to get files from several folders

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. :)

Categories

Resources