2010-02-22 253 views
7

我有一个程序比较两个文件夹中的文件。我想检测文件是否已被重命名,确定最新的文件(最近重命名),并更新旧文件中的名称以匹配。如何确定文件最近被重命名的时间?

要做到这一点,我会检查最新的文件是否与旧的文件一点一点地相同,如果是,只需重命名旧文件以匹配新文件。

问题是,我没有任何关键要告诉我哪个文件最近被重命名。

我会喜欢FileInfo.LastModified的一些属性,但对于已被重命名的文件。

我已经看过像FileSystemWatcher这样的解决方案,这并不是我正在寻找的。我希望能够随时运行我的同步器,而不必担心跟踪文件夹状态的某个专用进程。

任何想法?

回答

1

答:至少在NTFS,您可以将alternate data streams to a file。 在第一次同步时,您可以将ADS中的GUID附加到源文件以标记它们。

B:如果您没有对源代码的写入权限,请在您的目标存储库中存储同步文件的散列值。当源更改时,只需散列源文件,并且只在散列冲突时逐位进行比较。根据散列函数的质量和速度,这将为您节省大量时间。

+0

...当然,将它与'LastModified'结合起来。 – 2010-02-22 23:37:42

+0

我已经在每一端存储了目录的哈希值。逐位匹配数据已经成为可能。我只是希望当移动预先存在的文件在慢速网络上同步时,我可以节省一些带宽。它看起来像没有非NTFS特定的方式来做到这一点。 – 2010-02-23 17:17:59

+0

这也可以在映射的驱动程序(或网络共享)上工作,前提是源卷是NTFS。 如果你还没有找到它,这可能有一些帮助: http://www.codeproject.com/KB/cs/ntfsstreams.aspx – 2010-02-23 22:45:11

0

您可能会创建一个配置文件,其中包含文件夹中所有预期名称的列表,然后,如果该文件夹中的文件不是预期的名称列表的成员,则确定该文件已经重命名。但是,这会增加另一层工作,因为每次要将新文件添加到文件夹时都必须更改列表。

+0

这并不适用于我的工具。它意味着在两个方向上同步任何两个目录。 – 2010-02-22 22:51:40

+0

你有没有试过比较?这是您寻找的最佳工具。 – Aaron 2010-02-22 22:52:34

0

文件系统通常不会跟踪它。

由于您似乎在Windows上,您可以使用GetFileInformationByHandle()。 (对不起,我不知道C#等价物)。您可以使用返回的结构体中的“文件索引”字段来查看文件是否具有与您以前见过的相同的索引。请记住,硬链接也将具有相同的索引。

或者你可以以某种方式散列文件内容。

我不知道你想要做什么,所以我不能告诉你这两点之一是否合理。这可能是最合理的答案,“不,你做不到。”

+0

我很确定这不是OP正在寻找的东西,但它仍然是一个有趣的想法......可能比OP的测试计划更好,如果这两个文件是位相同的以确定重命名已执行。 – rmeador 2010-02-22 23:28:28

+0

这是个好主意,但是文件ID有很多问题。备注部分说:“存储在nFileIndexHigh和nFileIndexLow成员中的标识符被称为文件ID。[如此高索引和低索引=> **文件ID **]支持**文件ID ** s是文件特定于系统的[所以,不是所有的文件系统都可以支持它... NTFS可能会这样做,谁知道其他的文件系统是否会这样做]。文件ID不能保证随着时间的推移是唯一的,因为文件系统可以自由地重复使用[我想]时间快照,在某些情况下,文件的文件ID可能会随着时间而改变。“ – Alexandru 2014-11-07 20:29:45

1

如果您在NTFS驱动器上运行,则可以启用change journal,然后您可以查询重命名事件等内容。但是,您需要成为一名管理员才能使用它,并且会使用磁盘空间。不幸的是,我不知道阅读期刊的任何具体的C#实现。

0

我会用存储上次更新时间的2个目录中的(所有?)文件的CRC值(例如,CRC example)与CRC值,文件名等进行比较。之后,通过CRC查找mach列表然后使用日期值来决定要做什么。

+0

我已经这样做了。问题是重命名文件不会修改任何时间戳。 – 2010-02-23 17:14:16

+0

哦 - 据我所知,你不能重命名文件,也不能修改它的时间戳。如果可以的话,它会是一个相当低级别的API调用(不可能由C#公开) – 2010-02-23 21:06:55