我正在尝试编写一个基本同步程序来在两个目录之间复制文件。
计划是拥有已经复制的文件的某种数据库,因此当程序扫描目录时,它可以选择它已经复制的内容以及它需要再次复制的内容,即修改过的文件或新文件。
我不确定如何处理的问题之一是我应该如何处理用户重命名的文件。我怎么知道重命名的文件实际上是与数据库中列出的文件相同的文件,尽管名称不同。是否有程序可以提取的基础文件ID?我希望代码是可移植的,因此考虑到文件系统会有所不同,这可能会使这更加困难。
我在想我可以记下每个文件的大小和创建日期,并将这些信息保存在数据库中,以确定文件是否实际上只是重命名。如果两个文件具有相同的信息大小/日期,我可以存储哈希或其他东西来区分它们,但我不知道它有多高效。
有什么建议吗? (我正在使用C ++ / QT)
答案 0 :(得分:2)
要在应用程序运行时跟踪给定文件夹中文件的更改,请参阅QFileSystemWatcher
,在调用QFileSystemWatcher::addPath
后,您可以使用该文件跟踪目录中的所有文件更改("directory/to/watch/")
:
修改文件时会发出
fileChanged()
信号, 重命名或从磁盘中删除。同样,directoryChanged()
信号 在修改或删除目录或其内容时发出。 请注意QFileSystemWatcher
一旦有文件就会停止监视文件 已经重命名或从磁盘和目录中删除 从磁盘中删除。
为了在重命名文件后继续跟踪文件,只需再次使用QFileSystemWatcher::addPath()
重新启用它们。
在重命名操作期间当您的应用程序未运行时,您必须观看文件的内容(,如果您还想要覆盖文件被删除时的情况)复制回来,linux上的inode /其他文件系统类型上的任何内容都已更改)。
这可以使用MD5总和来完成,但它需要您的应用程序读取整个文件,对于大于10兆字节的文件来说,这可能会很慢。如果这个缺点可以接受,只需保存QCryptographicHash::hash
(file.readAll(), QCryptographicHash::Md5)
返回的MD5总和。当然,在某些极端情况下您会发生哈希冲突,但对于大多数应用程序而言,这应该不是问题。但请注意,可以发生,您将无法检测到内容的更改。另请注意,上面的简单单行程序是阻塞,并在计算MD5总和之前将整个文件读入内存。使用QCryptographicHash
提供的逐步MD5总和计算(使用addData()
和result()
代替)将文件“流式化”到MD5计算中。
在读取整个内容之前比较文件大小而不是创建MD5总和在大多数情况下都会起作用(更改不会导致更改导致相同的文件大小;在这种情况下,您可以回退到MD5总和比较)。但是在您注意到更改之后,无论如何都需要读取MD5总和,以便能够检测到未来的更改!
答案 1 :(得分:0)
在Unix下,您可以使用inode
获取文件的stat
号码。