问题
I have directory named Updates that inside has many folders named Update10, Update15,Update13 and so on. I need to be able to get the most recent update by comparing the numbers on the folder name and return the path to that folder. Any help would be aprecciated
回答1:
You can use LINQ:
int updateInt = 0;
var mostRecendUpdate = Directory.EnumerateDirectories(updateDir)
.Select(path => new
{
fullPath = path,
directoryName = System.IO.Path.GetFileName(path) // returns f.e. Update15
})
.Where(x => x.directoryName.StartsWith("Update")) // precheck
.Select(x => new
{
x.fullPath, x.directoryName,
updStr = x.directoryName.Substring("Update".Length) // returns f.e. "15"
})
.Where(x => int.TryParse(x.updStr, out updateInt)) // int-check and initialization of updateInt
.Select(x => new { x.fullPath, x.directoryName, update = updateInt })
.OrderByDescending(x => x.update) // main task: sorting
.FirstOrDefault(); // return newest update-infos
if(mostRecendUpdate != null)
{
string fullPath = mostRecendUpdate.fullPath;
int update = mostRecendUpdate.update;
}
A cleaner version uses a method that returns an int?
instead of using the local variable as out-parameter because LINQ should not cause such side-effects. They could be harmful.
One note: currently the query is case sensitive, it won't recognize UPDATE11
as valid directory. If you want to compare case-insensitive you have to use the appropriate StartsWith
overload:
.....
.Where(x => x.directoryName.StartsWith("Update", StringComparison.InvariantCultureIgnoreCase)) // precheck
.....
回答2:
This function uses LINQ to get the last update directory path.
public string GetLatestUpdate(string path)
{
if (!path.EndsWith("\\")) path += "\\";
return System.IO.Directory.GetDirectories(path)
.Select(f => new KeyValuePair<string, long>(f, long.Parse(f.Remove(0, (path + "Update").Length))))
.OrderByDescending(kvp => kvp.Value)
.First().Key;
}
回答3:
The best approach is to use modified date as comments in question suggests. however to sort strings as numbers you can go for making use of IComparer. This has already been done and can be found in here
edit with sample
after you get the directories:
string[] dirs = System.IO.Directory.GetDirectories();
var numComp = new NumericComparer();
Array.Sort(dirs, numComp);
the last item in dirs is your last "modified" directory.
回答4:
If you can rely on the creation date of the folders, you can simplify this by making use of MoreLinq's MaxBy():
string updatesFolder = "D:\\TEST\\Updates"; // Your path goes here.
var newest = Directory.EnumerateDirectories(updatesFolder, "Update*")
.MaxBy(folder => new DirectoryInfo(folder).CreationTime);
For reference, an implementation of MaxBy()
is:
public static class EnumerableMaxMinExt
{
public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
{
return source.MaxBy(selector, Comparer<TKey>.Default);
}
public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector, IComparer<TKey> comparer)
{
using (IEnumerator<TSource> sourceIterator = source.GetEnumerator())
{
if (!sourceIterator.MoveNext())
{
throw new InvalidOperationException("Sequence was empty");
}
TSource max = sourceIterator.Current;
TKey maxKey = selector(max);
while (sourceIterator.MoveNext())
{
TSource candidate = sourceIterator.Current;
TKey candidateProjected = selector(candidate);
if (comparer.Compare(candidateProjected, maxKey) > 0)
{
max = candidate;
maxKey = candidateProjected;
}
}
return max;
}
}
}
来源:https://stackoverflow.com/questions/36597030/searching-for-the-newest-update-in-a-directory-c-sharp