Reputation: 16675
I need to get all the files from a directory, ordered by the date which is present as part of the files name:
James_2015.06.27.pdf
Anna_2017.01.17.pdf
Timmy_2017.02.19.pdf
Currently, I'm using this, which only sorts the files by Name
.
DirectoryInfo info = new DirectoryInfo(path);
FileInfo[] files = info.GetFiles(filter).OrderBy(p => p.Name).ToArray();
Any ideas how can I achieve this?
Upvotes: 0
Views: 371
Reputation: 22038
You need to parse the filename:
DirectoryInfo info = new DirectoryInfo(path);
FileInfo[] files = info.GetFiles(filter)
.OrderBy(p => Path.GetFileNameWithoutExtension(p.FullName).Split('_')[1])
.ToArray();
But this is error prone.
Using linq
Like I said, this is error prone, I would probably write something like this:
DirectoryInfo info = new DirectoryInfo(path);
FileInfo[] files = (from fileInfo in info.GetFiles(filter)
let splitted = Path.GetFileNameWithoutExtension(fileInfo.FullName).Split('_')
where splitted.Length > 1
orderby splitted[1]
select fileInfo).ToArray();
A better way would be parsing the datetime and sort on it.
This will also filter on the files that doesn't have a valid date within the filename.
private DateTime? ParseFilename(FileInfo fileInfo)
{
var parts = Path.GetFileNameWithoutExtension(fileInfo.FullName).Split('_');
if (parts.Length < 1)
return null;
DateTime result;
if (!DateTime.TryParse(parts[1], out result))
return null;
return result;
}
Usage:
DirectoryInfo info = new DirectoryInfo(path);
FileInfo[] files = (from fileInfo in info.GetFiles(filter)
let DateTime = ParseFilename(fileInfo)
where DateTime.HasValue
orderby DateTime.Value
select fileInfo).ToArray();
Upvotes: 4
Reputation: 471
I would create a dictionary with the Filename as Key and the value would be a substring from the filename and only contain the date.
You can loop over your DirectoryEntrys and add them to the dictionary in a loop, the algorithm would be like that:
string filename1 = "asbdahszd2018.02.01.pdf";
string filename2 = "foobar2018.02.01.pdf";
Dictionary<string, string> myDict = new Dictionary<string,string>();
myDict.Add(filename1, filename1.Substring(filename1.Length - 14, 10));
myDict.Add(filename2, filename2.Substring(filename2.Length - 14, 10));
myDict.OrderBy(item => item.Value);
Upvotes: 0
Reputation: 1871
This should work for you:
DirectoryInfo info = new DirectoryInfo(path);
FileInfo[] files = info.GetFiles(filter).OrderBy(p => Path.GetFileNameWithoutExtension(p.Name).Split('_').Last()).ToArray();
Upvotes: 1