![]() |
1
103
校验和比较很可能比逐字节比较慢。 为了生成校验和,您需要加载文件的每个字节,并对其执行处理。然后你必须在第二个文件中这样做。处理过程几乎肯定会比比较检查慢。 至于生成校验和:使用加密类可以很容易地做到这一点。这里有一个 short example of generating an MD5 checksum 用C。 但是,如果您可以预先计算“测试”或“基本”情况的校验和,则校验和可能更快并且更有意义。如果您有一个现有文件,并且您正在检查新文件是否与现有文件相同,则预先计算“现有”文件上的校验和意味着只需要对新文件执行一次磁盘IO。这可能比逐字节比较快。 |
![]() |
2
117
最慢的方法是逐字节比较两个文件。我能想到的最快的方法是进行类似的比较,但不是一次一个字节,而是使用一个大小为Int64的字节数组,然后比较得到的数字。 我想到的是:
在我的测试中,我看到这比简单的readbyte()场景快了3:1。平均超过1000次运行,我在1063ms时得到了这个方法,下面的方法(逐字节比较)在3031ms时得到了这个方法。哈希总是以大约865ms的平均速度返回到次秒。这个测试使用了一个大约100MB的视频文件。 以下是我用于比较的readbyte和hashing方法:
|
![]() |
3
33
除了 里德·科普西 答案是:
例如,如果这两个文件的长度不同,那么您就知道它们不可能是相同的,而且您甚至不需要比较它们的实际内容。 |
![]() |
4
31
如果你 D.O.O.S. 决定你真的需要 逐字节比较 (关于散列的讨论,请参见其他答案),那么一行解决方案是:
与其他一些已发布的答案不同,这对于 任何类型的文件: 二进制、文本、媒体、可执行文件等,但作为 满的 二元的 比较 ,不同的文件 只有 以“不重要”的方式(例如 BOM , line-ending , character encoding ,将始终考虑媒体元数据、空白、填充、源代码注释等。) 不等 .
这段代码将两个文件全部加载到内存中,因此不应将其用于比较
巨大的
文件夹。除此之外,完全加载并不是真正的惩罚;事实上,对于预期小于的文件大小,这可能是一个最佳的.NET解决方案。
85K
,因为在
此外,对于这种工作日场景,关注的是通过
另一方面,上述代码
不
包括紧急中止
大小不同的文件
哪一个
可以
提供有形(可能可测量)的绩效差异。这个是有形的,因为,而文件长度在
如果(等效的),您还可以扩展此项以避免二次提取。
|
![]() |
5
15
如果不以8字节的小块读取,而是循环读取更大的块,则速度会更快。我把平均比较时间缩短到1/4。
|
![]() |
6
15
唯一可能比逐字节比较稍微快一点的校验和比较的是,您一次读取一个文件,这在一定程度上减少了磁盘头的查找时间。然而,计算散列值所增加的时间很可能会消耗掉这一微小的收益。 当然,校验和比较只有在文件相同的情况下才有可能更快。如果不是,逐字节比较将在第一个差异处结束,从而使其更快。 您还应该考虑到哈希代码比较只会告诉您 很可能 文件是相同的。要100%确定,您需要进行逐字节比较。 例如,如果散列代码是32位,则大约99.9999999 8%的人确定如果散列代码匹配,文件是相同的。这接近100%,但如果你真的需要100%的确定性,那就不是了。 |
![]() |
7
10
编辑: 这种方法会 不 比较二进制文件!
在.NET 4.0中,
这意味着你可以使用:
|
![]() |
8
6
老实说,我认为你需要尽可能地修剪你的搜索树。 逐字节进行前要检查的内容:
此外,一次读取大的块会更有效,因为驱动器读取顺序字节的速度更快。一个字节一个字节地进行不仅会导致更多的系统调用,而且如果两个文件都在同一个驱动器上,它还会使传统硬盘驱动器的读取头更频繁地来回搜索。 将块A和块B读取到字节缓冲区中,并进行比较(不要使用array.equals,请参见注释)。调整块的大小,直到达到你认为内存和性能之间的良好平衡。您也可以多线程比较,但不要多线程读取磁盘。 |
![]() |
9
2
我的实验表明,调用stream.readbyte()的次数更少肯定有帮助,但是使用bitconverter打包字节与比较字节数组中的字节没有太大区别。 因此,可以用最简单的循环替换上面注释中的“math.ceiling and iterations”循环:
我想这是因为bitconverter.toint64在比较之前需要做一些工作(检查参数,然后执行位移位),这与比较两个数组中8个字节的工作量相同。 |
![]() |
10
2
我的答案是@lars的派生,但修复了
或者,如果你想变得超级棒,你可以使用异步变量:
|
![]() |
11
1
如果文件不太大,可以使用:
只有当哈希值对存储有用时,才可以比较哈希值。 (把代码编辑得更清晰。) |
![]() |
12
1
对于长度相同的大文件的另一个改进可能是不按顺序读取文件,而是比较或多或少的随机块。 可以使用多个线程,从文件中的不同位置开始,然后向前或向后比较。 这样,您就可以在文件的中间/末尾检测更改,速度比使用顺序方法更快。 |
![]() |
13
1
如果只需要比较两个文件,我想最快的方法是(在C语言中,我不知道它是否适用于.NET)
如果您需要查找一组n个文件中是否存在重复的文件,那么最快的方法无疑是使用哈希来避免n向逐位比较。 |
![]() |
14
1
相当有效的东西:
|
![]() |
15
1
下面是一些实用程序函数,允许您确定两个文件(或两个流)是否包含相同的数据。 我提供了一个“快速”版本,它是多线程的,因为它比较不同线程中使用任务的字节数组(每个缓冲区都是从每个文件中读取的内容填充的)。 正如预期的那样,它更快(大约快3倍),但它消耗更多的CPU(因为它是多线程的)和更多的内存(因为它需要每个比较线程使用两个字节的数组缓冲区)。
|
![]() |
16
0
我认为有些应用程序“hash”比逐字节比较快。 如果你需要与其他人比较一个文件,或者有一个可以更改的照片的缩略图。 这取决于它在哪里以及如何使用。
在这里,你可以得到最快的。
或者,我们可以将哈希保存在数据库中。 希望这能有所帮助 |
![]() |
17
0
另一个答案来自@chsh。MD5与文件的using和shortcuts相同,文件不存在,长度不同:
|
![]() |
18
-1
我发现这个方法可以很好地比较没有读取数据的长度,然后比较读取字节序列
|
![]() |
A B · C#Excel自动调整列避免长文本时出错 8 月前 |
![]() |
Megrez7 · C#ToArray转换合并为一行,导致数组元素更改 8 月前 |
![]() |
Aycon · 在工厂方法中释放部分创建的对象的正确方法是什么? 8 月前 |
|
Sei · Avalonia/WPF将路由器传递到控制模板 8 月前 |