比较文件版本是不是有一种不那么复杂的方法?

Posted

技术标签:

【中文标题】比较文件版本是不是有一种不那么复杂的方法?【英文标题】:Is there a less convoluted way to compare file versions?比较文件版本是否有一种不那么复杂的方法? 【发布时间】:2014-03-21 18:50:58 【问题描述】:

我编写了一个函数来比较客户端当前拥有的文件版本和服务器上文件的最新版本。客户端将“quad”(Major.Minor.Build.Private)版本号作为字符串传递给服务器,然后服务器使用FileVersionInfo:

// clientFileVersion will be in "quad" format, a la "3.1.4.1"
private bool ServerFileIsNewer(string clientFileVersion, FileVersionInfo serverFile)

    // Don't say I never learned nuthin' from Steve McConnell
    const int MAJOR_INDEX = 0;
    const int MINOR_INDEX = 1;
    const int BUILD_INDEX = 2;
    const int PRIVATE_INDEX = 3;

    string[] versionStrArray = clientFileVersion.Split('.');
    int FileMajorPartClient;
    Int32.TryParse(versionStrArray[MAJOR_INDEX], out FileMajorPartClient);
    int FileMinorPartClient;
    Int32.TryParse(versionStrArray[MINOR_INDEX], out FileMinorPartClient);
    int FileBuildPartClient;
    Int32.TryParse(versionStrArray[BUILD_INDEX], out FileBuildPartClient);
    int FilePrivatePartClient;
    Int32.TryParse(versionStrArray[PRIVATE_INDEX], out FilePrivatePartClient);

    int FileMajorPartServer = serverFile.FileMajorPart;
    int FileMinorPartServer = serverFile.FileMinorPart;
    int FileBuildPartServer = serverFile.FileBuildPart;
    int FilePrivatePartServer = serverFile.FilePrivatePart;

    return ((FileMajorPartClient < FileMajorPartServer) ||
           ((FileMajorPartClient == FileMajorPartServer) && (FileMinorPartClient < FileMinorPartServer)) ||
           ((FileMinorPartClient == FileMinorPartServer) && (FileBuildPartClient < FileBuildPartServer)) ||
           ((FileBuildPartClient == FileBuildPartServer) && (FilePrivatePartClient < FilePrivatePartServer)));

但后来我意识到,如果客户端版本是 2.1.1.1 而服务器版本是 1.1.2.1,我的 megaboolean return 语句将会失败

IOW,它表明服务器版本较新,而实际上(当然)不是。

所以我想我会添加更多的布尔逻辑,例如:

if   (FileMajorClient > FileMajorServer) || 
     ((FileMajorClient == FileMajorServer) && (FileMinorClient > FileMinorServer)) ||
     ((FileMajorClient == FileMajorServer) && (FileMinorClient == FileMinorServer) && (FileBuildClient > FileBuildServer))

    return false;

else

    return ((FileMajorPartClient < FileMajorPartServer) ||
           ((FileMajorPartClient == FileMajorPartServer) && (FileMinorPartClient < FileMinorPartServer)) ||
           ((FileMinorPartClient == FileMinorPartServer) && (FileBuildPartClient < FileBuildPartServer)) ||
           ((FileBuildPartClient == FileBuildPartServer) && (FilePrivatePartClient < FilePrivatePartServer)));

...但正如你所看到的,它正在变成一个疯狂的大球/意大利面条混乱的疯狂。

必须有一种更好、更简单、更易于理解/可维护的方法来比较两个文件版本。但是什么/如何?

更新

使用Servy的答案,这是现在的方法:

private bool ServerFileIsNewer(string clientFileVersion, FileVersionInfo serverFile)

    Version client = new Version(clientFileVersion);
    Version server = new Version(string.Format("0.1.2.3", serverFile.FileMajorPart, serverFile.FileMinorPart, serverFile.FileBuildPart, serverFile.FilePrivatePart));
    return server > client;

像未吹的哨子一样干净,像 Joe Friday 的梦想见证者一样简洁,像 Grace Kelley 一样优雅。

【问题讨论】:

无实例,if( Version.Parse("1.1.2.1") > Version.Parse("2.1.2") ) 【参考方案1】:

使用Version 类:

Version first = new Version("1.1.2.1");
Version second = new Version("2.1.1.1");
bool b = first >= second;

【讨论】:

【参考方案2】:

Servy's answer 是您应该选择的。

但是,对于其他情况,当您有嵌套条件并且您没有从已经实现比较的类中受益时,最直接的方法是使用多个条件并“提前退出”你可以。例如,在检查版本时,您可以这样做:

if (FileMajorClient > FileMajorServer)
    return false;
if (FileMajorClient < FileMajorServer)
    return true;

// Major versions are equal, now do the same thing for minor part
if (FileMinorClient != FileMinorServer)
    return (FileMinorClient < FileMinorServer);

请注意,主要版本检查的编写方式可能与次要版本检查相同。这只是编写相同逻辑的两种不同方式。

然后您可以对剩余的每个部分执行此操作。

if (FileBuildPartClient != FileBuildPartServer)
    return (FileBuildPartClient < FileBuildPartServer);

return (FilePrivatePartClient <= FilePrivatePartServer);

在每个步骤中,您都消除了客户端和服务器版本不匹配的情况。

这不像写一个单一的条件语句那么“聪明”,但它很容易理解并且很容易证明是正确的。

【讨论】:

谢谢,吉姆;正如一位圣人曾经写过的那样,“聪明的把戏”(现在解释)是为鸟类服务的。我的巴洛克贝多夫方法已被简化为爵士乐(我喜欢这样)。

以上是关于比较文件版本是不是有一种不那么复杂的方法?的主要内容,如果未能解决你的问题,请参考以下文章

省选模拟赛 环

如何大批量比较class文件

各种排序算法时间复杂度稳定性初始序列是否对元素比较次数有关

3. 快速排序

Beyond Compare如何比较文件内容的差异 如何对比文件内容的差异

C++ Builder 中操作XML文件