【发布时间】:2015-09-10 06:17:00
【问题描述】:
我正在用 C++ 构建一个小型同步实用程序,主要供个人使用。
假设我们有两个将被同步的目录“A”和“B”。在某些时候,必须将 A 中的新文件复制到 B。我目前使用的逻辑是:
browse directory 'A'
for each 'A/afile'
copy A/afile to B/afile
endfor
for each 'A/adirectory'
recurse into 'A/adirectory'
endfor
这很好,直到我注意到使用上面的方法,A 中的所有文件每次都复制到 B。所以,如果 A/afile 和 B/afile 不同,我只想执行复制操作.
所以,我的问题是,如何以快速和跨平台(希望如此)的方式比较它们?为每个文件计算 MD5 校验和之类的东西会很快吗?
关键是,由于可能会针对大量文件对进行文件比较,所以我想要既可靠又快速的东西。我所说的快速是指“繁重且耗时”的任务应该是实际的复制操作,而不是文件检查。
PS。我还尝试寻找“技巧”,例如比较文件大小和修改时间,但没有成功。
编辑
在考虑了下面的答案后,我最终会检查两个文件是否相同:
if optimize_speed then
if A/afile is newer then no (cause A/afile is the 'source' file)
if B/afile is newer then compare byte-to-byte and decide
else
compare byte-to-byte and decide
end
【问题讨论】:
-
要么使用 Qt 之类的框架(或任何其他具有文件系统模块的框架),要么使用系统 API。比较修改时间,不要比较大小,因为你可能会更改 txt 文件中的某些行,它的大小不会改变。
-
几乎所有文件系统都有修改时间戳。您可以使用它来检查
A中的文件是否在B中的相应文件之后被修改。 -
问题是,如果我将A/afile复制到B/afile,那么'B/afile'的修改时间将是复制操作的时间,而不是A的修改时间/一份文件。但是,作为通用解决方案,该程序提供了两种同步模式:“镜像”和“附加”:附加已经可以正常工作,因为我只复制较新的文件。然而,镜像模式应该丢弃在 B/afile 中所做的任何更改,因此修改检查是不够的,因为 B/afile 可能在 A/afile 之后被更改。这就是为什么我认为文件比较是要走的路,除非.......
-
除非有更简单、更清洁、更快捷的方法。另外,我想避免像 Qt 这样的小任务那样依赖。如果有帮助,您可以在此处找到源代码(查找函数:copy_all_files()、copy_new_and_updated_files()、doMirrorSync()、doAppendSync())。 github.com/neoaggelos/synctool -
您可能想看看 Linux
cmp命令行工具的源代码。它经过了很好的优化,运行cmp --silent file1 file2具有您所追求的确切语义。