2

我正在尝试编写一个基本的同步程序来在两个目录之间复制文件。

计划是拥有某种已经复制的文件的数据库,因此当程序扫描目录时,它可以挑选出它已经复制的内容以及需要再次复制的内容,即修改过的文件或新文件。

我不确定如何解决的问题之一是我应该如何处理由用户重命名的文件。我怎么知道重命名的文件实际上与数据库中列出的文件相同,尽管名称不同。是否有程序可以提取的基础文件 ID?我希望代码是可移植的,因此考虑到文件系统会有所不同,这可能会使这变得更加困难。

我在想我可以记下每个文件的大小和创建日期,并将该信息保存在数据库中,以确定该文件是否实际上只是重命名了。如果两个文件具有相同的信息大小/日期,我可以存储一个哈希或其他东西来区分它们,但我不知道这会有多有效。

有什么建议么?(我正在使用 C++/QT)

4

2 回答 2

2

要在应用程序运行时跟踪给定文件夹中文件的更改,请参阅QFileSystemWatcher,使用它可以在调用后跟踪目录中的所有文件更改:QFileSystemWatcher::addPath("directory/to/watch/")

fileChanged()文件被修改、重命名或从磁盘中删除时发出信号。同样,directoryChanged()当目录或其内容被修改或删除时,也会发出信号。请注意,QFileSystemWatcher一旦文件被重命名或从磁盘中删除,就会停止监视文件,一旦从磁盘中删除目录,就会停止监视。

为了在重命名文件后继续跟踪文件,只需重新启用观看它们QFileSystemWatcher::addPath()再次使用。


当您的应用程序在重命名操作期间未运行时,您必须查看文件的内容(如果您还想涵盖文件已被删除并复制回来的情​​况,Linux 上的 inode / 其他文件上的任何内容系统类型已更改)。

这可以使用 MD5 和来完成,但它需要您的应用程序读取整个文件,这对于大于 10 兆字节的文件可能会很慢。如果这个缺点是可以接受的,只需保存返回的 MD5 和。当然,在某些极端情况下您会遇到哈希冲突,但对于大多数应用程序来说,这应该不是问题。但请注意,可能无法检测到内容的更改。另请注意,上面的简单单行是阻塞的,并且在计算 MD5 和之前将整个文件读入内存。使用(使用and代替)提供的逐步 MD5 总和计算将文件“流式传输”到 MD5 计算中。QCryptographicHash::hash(file.readAll(), QCryptographicHash::Md5)QCryptographicHashaddData()result()

在大多数情况下,在读取全部内容之前比较文件大小而不是创建 MD5 总和会起作用(更改导致相同文件大小的情况并不常见;在这种情况下,您可以回退到 MD5 总和比较) . 但是在你注意到一个变化之后,无论如何你都需要读取 MD5 和,以便能够检测到未来的变化!

于 2012-06-21T14:19:56.893 回答
0

在 Unix 下,您可以inode使用stat.

于 2012-06-21T14:27:34.807 回答