如何获取最新或最大文件夹版本?

How to get a latest or max folder version?

我有一些版本文件夹,例如 Vx_x_x

我想检索最大文件夹版本。

例如:

文件夹包含,

 V8_2_1
 V9_3_2
 V10_4_1

我想检查 V 旁边的最大数量等等以获得最新的文件夹版本。

我能够获取文件夹列表,但对如何获取最大数量感到困惑。如果有人可以建议我,我会很有帮助。谢谢你。

private static void GetFolderVersion()
{
     string startFolder = @"C:\Version\";
     System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(startFolder);
     IEnumerable<System.IO.DirectoryInfo> directoryList = dir.GetDirectories("*.*", System.IO.SearchOption.AllDirectories);           
}

虽然这可能确实有效,但建议使用@jbartuszek 的解决方案,该解决方案使用 Version class.

按照这些思路可以做到这一点,但请注意,这是我的想法,用记事本写成,因此可能不会构建或包含某种形式的逻辑错误。这只是说明了它的要点:

string[] version = folderName.Split('_');
string[] otherVersion = otherFolderName.Split('_');

然后您编写一个方法来检查版本的各个部分:

private int CompareVersions(string[] version, string[] otherVersion)
{
    //we won't need the first character (the 'V')
    int vmajor = int.Parse(version[0].Substring(1));
    int vminor = int.Parse(version[1]);
    int vrevision = int.Parse(version[2]);

    int ovmajor = int.Parse(otherVersion[0].Substring(1));
    int ovminor = int.Parse(otherVersion[1]);
    int ovrevision = int.Parse(otherVersion[2]);

    int majorCompare = vmajor.CompareTo(ovmajor);

    //check if major already decides outcome
    if(majorCompare != 0)
    {
        return majorCompare;
    }

    int minorCompare = vminor.CompareTo(ovminor);

    //then if major equal, check if minor decides outcome
    if(minorCompare != 0)
    {
        return minorCompare;
    }

    //lastly, return outcome of revision compare
    return vrevision.CompareTo(ovrevision);
}

这就是您比较两个文件夹名称的方式。如果您想获得最大文件夹版本,您可以 foreach 文件夹名称:

//we'll start out by assigning the first folder name as a preliminary max
string maxFolder = folderNames[1];
string[] maxFolderVersion = maxFolder.Split('_');

foreach(string folderName in folderNames)
{
    if(CompareVersions(folderName.Split('_'), maxFolderVersion) > 0)
    {
        maxFolder = folderName;
    }
}

如果文件都符合您提供的模式,我很想使用正则表达式提取版本信息,然后选择最高值,从主要版本开始计算。

更新:用适合您的情况的正确前缀替换正则表达式中的 V。

var regex = new Regex(@"^V(\d+)_(\d+)_(\d+)$", RegexOptions.Compiled);
var versions = directoryList 
    .Select(f => regex.Match(f))
    .Where(m => m.Success)
    .Select(m => new
    {
        Major = Int32.Parse(m.Groups[1].Value),
        Minor = Int32.Parse(m.Groups[2].Value),
        Patch = Int32.Parse(m.Groups[3].Value)
    }).ToList();

    var major = versions.Max(a => a.Major);
    versions = versions
        .Where(a => a.Major == major)
        .ToList();

    var minor = versions.Max(a => a.Minor);
    versions = versions
        .Where(a => a.Minor == minor)
        .ToList();

    var patch = versions.Max(a => a.Patch);
    versions = versions
        .Where(a => a.Patch == patch)
        .ToList();

    var newest = versions.First();

    var filename = String.Format("V_{0}_{1}_{2}", newest.Major, newest.Minor, newest.Patch);

我会考虑使用内置的 System.Version 类型。假设所有目录名称的格式都相同 "VX_Y_Z"(其中 X、Y 和 Z 代表一位或多位数字,V 代表文字 "V"),下面的代码将执行您想要的操作:

public string GetMaxVersion(IEnumerable<string> directoryNames)
{
    var vDict = directoryNames.ToDictionary(
        s => new Version(s.Substring(1).Replace("_", ".")),
        s => s);
    var maxKey = vDict.Keys.Max();
    return vDict[maxKey];
}

这里我们构建一个版本字典到文件名映射(注意我们将字符串格式从 "VX_Y_Z" 更改为 "X.Y.Z" 以便能够创建一个 System.Version 对象)。剩下的就是检索所有字典键的最大值,以及 return 分配给给定键的值,这将是您要查找的目录名称。

更新: 为了完整起见,这里有一段代码使用了上面的方法并处理了所有事情:

public string GetMaxVersionDirectory(string rootDirectory)
{
    var dirNames = Directory.GetDirectories(rootDirectory, "V*_*_*")
        .Select(dir => Path.GetFileName(dir));
    return GetMaxVersion(dirNames);
}

在您的情况下,您需要将 @"C:\Version" 作为 rootDirectory 参数传递。

您可以使用数学方法。假设您版本的每个部分都可以达到最大值。 1000。所以基数是 1000。版本部分是你的系数,指数是在你的循环中构建的。通过对 coefficent*base^exp 求和,您可以得到一个值,您可以比较该值以获得最高版本:

private static string GetHighestFolderVersion()
{

    string startFolder = @"C:\Version\";
    System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(startFolder);
    IEnumerable<System.IO.DirectoryInfo> directoryList = dir.GetDirectories("*.*", System.IO.SearchOption.AllDirectories);

    KeyValuePair<string, long> highestVersion = new KeyValuePair<string, long>("", 0);
    foreach (System.IO.DirectoryInfo dirInfo in directoryList)
    {
        string versionOrigName = dirInfo.Name;
        string versionStr = versionOrigName.Substring(1);
        List<string> versionParts = versionStr.Split('_').ToList<string>();

        long versionVal = 0;
        int exp = 0;
        for (int i = versionParts.Count - 1; i > -1; i--)
        {
            versionVal += (long.Parse(versionParts[i]) * (long)(Math.Pow(1000, exp)));
            exp++;
        }

        if (versionVal > highestVersion.Value)
        {
            highestVersion = new KeyValuePair<string, long>(versionOrigName, versionVal);
        }
    }

    return highestVersion.Key;
}