我需要将目录A中的文件同步到目录B.我检查A中的文件,然后逐个将它们与B中的文件进行比较。如果在B中找到与A同名的文件,我通过比较它们的大小来检查文件是否不同。如果文件大小不同,我将其记录下来并转到下一个文件。但是,如果文件大小相同,我需要验证文件的内容是否也不同。为此,我想到了创建两个文件的哈希值并进行比较。这是更好还是我应该逐字节比较文件?还请说明为什么你会选择其中一种方法。
我正在使用C#(.NET 4)并且需要保留B上的所有文件,同时在A上复制新添加的文件并报告(和跳过)任何重复文件。
感谢。
编辑:这个作业将每晚运行,我可以选择只在目录B上存储文件的哈希值,目录A将动态填充,所以我不能预先散列这些文件。此外,哪种哈希算法更适合此目的,因为我也希望避免哈希冲突。答案 0 :(得分:1)
如果您需要同步文件,还可以比较另一件事:文件日期 - 如果这有任何不同,则文件很可能已更改。
此外,在大多数情况下,哈希(我会选择md5或sha1 - 而不是因为有限的值范围而非因为频繁的碰撞而导致的crc)就足够了。如果这些哈希值相等,你应该进行逐字节比较。当然这是一个额外的步骤,但如果有的话,它很少需要。
实际上你应该在B上保存哈希值,所以你不需要每次都重新计算它,但是你必须确保在不更新哈希值的情况下不能更改B上的文件。
答案 1 :(得分:0)
你已经有了一个哈希函数。您的哈希函数是file-->(filename, filesize)
。此外,由于目录中只能有一个具有给定文件名的文件,因此保证每个文件每次运行不会有多个冲突。
你问你是否需要更好的。好吧,我不知道,你已经拥有的哈希函数表现是否足够?如果它对你来说足够了,你就不需要更好的哈希函数。
答案 2 :(得分:0)
如果您只使用哈希码来比较两个文件,那么如果哈希码不同,您可以确定文件不同。
但是如果哈希码相同,那么你不确定文件是否真的相同。
如果使用32位哈希码,那么即使哈希码相同,文件也会有1 ^ 2 ^ 32的可能性。对于64位哈希码,机会自然是1比2 ^ 64。
存储B上所有文件的哈希码将使初始比较更快,但是如果两个哈希码相同,则必须决定该怎么做。你抓住机会并假设它们都是一样的吗?或者,在发现具有相同散列的两个文件后,您是否继续进行逐字节比较?
请注意,如果您在之后进行逐字节比较,则计算了文件的哈希码,您将最终访问文件内容两次。如果大部分文件相同,这可能会使哈希码使用速度变慢。和往常一样,你必须做一些时间来看哪个更快。
如果你可以忍受错误地假设两个文件相同的可能性,你可以避免确认比较......但我不想自己冒这个机会。
总而言之,我可能只是每次都进行比较,而不是为了使用散列而烦恼(除了你在比较文件名和大小时已经做过的事情)。
请注意,如果您发现几乎所有按文件名和大小匹配的文件也相同,那么使用散列几乎肯定会减慢速度。