3 回答
TA贡献1982条经验 获得超2个赞
校验和比较最有可能比逐字节比较慢。
为了生成校验和,您需要加载文件的每个字节,并对其进行处理。然后,您必须在第二个文件上执行此操作。处理几乎肯定会比比较检查慢。
至于生成校验和:您可以使用密码学类轻松地做到这一点。这是使用C#生成MD5校验和的简短示例。
但是,如果可以预先计算“测试”或“基本”情况的校验和,则校验和可能会更快并且更有意义。如果您有一个现有文件,并且正在检查一个新文件是否与现有文件相同,则在“现有”文件上预先计算校验和将意味着只需要一次在磁盘上执行DiskIO。新文件。这可能比逐字节比较要快。
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两次(也未显示),您也可以扩展它以避免二次获取。
- 3 回答
- 0 关注
- 464 浏览
添加回答
举报