为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用.NET快速比较2个文件?

如何使用.NET快速比较2个文件?

C#
烙印99 2019-10-06 11:25:36
典型的方法建议通过FileStream读取二进制文件并逐字节比较它。校验和比较(例如CRC)会更快吗?是否有任何.NET库可以为文件生成校验和?
查看完整描述

3 回答

?
临摹微笑

TA贡献1982条经验 获得超2个赞

校验和比较最有可能比逐字节比较慢。


为了生成校验和,您需要加载文件的每个字节,并对其进行处理。然后,您必须在第二个文件上执行此操作。处理几乎肯定会比比较检查慢。


至于生成校验和:您可以使用密码学类轻松地做到这一点。这是使用C#生成MD5校验和的简短示例。


但是,如果可以预先计算“测试”或“基本”情况的校验和,则校验和可能会更快并且更有意义。如果您有一个现有文件,并且正在检查一个新文件是否与现有文件相同,则在“现有”文件上预先计算校验和将意味着只需要一次在磁盘上执行DiskIO。新文件。这可能比逐字节比较要快。


查看完整回答
反对 回复 2019-10-06
?
犯罪嫌疑人X

TA贡献2080条经验 获得超4个赞

如果你决定你真正需要一个完整的逐字节的比较(见散列讨论其他的答案),然后是一个在线的解决方案是:


bool filesAreEqual = File.ReadAllBytes(path1).SequenceEqual(File.ReadAllBytes(path2));

不像其他一些张贴的答案,这可以正确处理任何类型的文件:二进制,文本,媒体,可执行文件等,但作为一个完整的二进制比较,文件是不同的只是在“不重要”的方式(如BOM,线-结尾,字符编码,媒体元数据,空格,填充,源代码注释等)将始终被视为不相等。


此代码将两个文件全部加载到内存中,因此不应将其用于比较巨大的文件。除了这种考虑之外,满负荷并不是真正的代价。实际上,这对于预期小于85K的文件大小可能是一个最佳的.NET解决方案,因为其中的小分配.NET非常便宜,并且上面的代码将文件性能和优化最大程度地委托给CLR/ BCL。


此外,对于这样触目所及的情况下,约逐字节的比较的通过性能问题LINQ统计员(如下图所示)是没有实际意义的,因为击中盘所有文件I / O将大大超过,由几个数量级,带来的好处各种内存比较选择。例如,尽管实际上SequenceEqual 确实为我们提供了“最佳”的放弃第一次不匹配的功能,但是在已经获取了文件的内容之后,这几乎无关紧要,每个内容都是确认匹配所必需的。


另一方面,以上代码不包含针对不同大小文件的急切中止操作,这可以提供明显的(可能是可测量的)性能差异。这是有形的,因为尽管WIN32_FILE_ATTRIBUTE_DATA结构中的文件长度可用(无论如何都必须首先获取文件长度才能进行任何文件访问),但继续访问文件的内容却需要完全不同的获取,这有可能避免。如果您对此担心,那么解决方案将变成两行:


// slight optimization over the code shown above

bool filesAreEqual = new FileInfo(path1).Length == new FileInfo(path2).Length && 

       File.ReadAllBytes(path1).SequenceEqual(File.ReadAllBytes(path2));

如果(等效)Length值都被发现为零(未显示)和/或避免每个值都构造FileInfo两次(也未显示),您也可以扩展它以避免二次获取。


查看完整回答
反对 回复 2019-10-06
  • 3 回答
  • 0 关注
  • 464 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信