我有一个名为Updates的目录,里面有许多名为Update10、Update15、Update13等的文件夹。我需要能够通过比较文件夹名称上的数字来获得最新的更新,并返回该文件夹的路径。任何帮助都将被视为
您可以使用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;
}
更干净的版本使用返回int?
的方法,而不是使用局部变量作为out参数,因为LINQ不应该引起这样的副作用。它们可能有害。
需要注意的是:当前查询区分大小写,它不会将UPDATE11
识别为有效目录。如果你想比较不区分大小写,你必须使用适当的StartsWith
重载:
.....
.Where(x => x.directoryName.StartsWith("Update", StringComparison.InvariantCultureIgnoreCase)) // precheck
.....
此函数使用LINQ获取最后一个更新目录路径。
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;
}
最好的方法是按照有问题的注释所建议的那样使用修改后的日期。然而,要将字符串排序为数字,可以使用IComparer。这已经完成了,可以在这里找到
使用样本编辑
获得目录后:
string[] dirs = System.IO.Directory.GetDirectories();
var numComp = new NumericComparer();
Array.Sort(dirs, numComp);
dirs中的最后一项是您最后一个"修改"的目录。
如果你可以依赖文件夹的创建日期,你可以通过使用MoreLinq的MaxBy()
:来简化它
string updatesFolder = "D:\TEST\Updates"; // Your path goes here.
var newest = Directory.EnumerateDirectories(updatesFolder, "Update*")
.MaxBy(folder => new DirectoryInfo(folder).CreationTime);
作为参考,MaxBy()
的一个实现是:
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;
}
}
}