2010-09-30 62 views
5

我有一个实用程序,它处理目录中的一组文件 - 这个过程相对较慢(并且有很多文件)和所以我试图通过仅处理具有晚于最后处理日期的“最后修改”的文件来优化处理。Windows:如何确定一个文件自给定日期以来是否已被修改

通常这个效果很好,但是我发现复制文件不会改变最后修改日期,所以有各种复制文件的过程中会跳过某些被更改的文件的情况,例如:

  1. 用户在9:00处理目录。
  2. 的文件,然后从该目录复制和修改,使之具有9:30
  3. 最后修改日期的目录,然后在10:00
  4. 修改后的文件再次进行处理,然后复制回在10:30
  5. 目录最后的目录是在11:00

由于给定文件的修改日期是9点30分再次处理,并且目录在10:00最后处理的是该文件当它不应该跳过时跳过。

不幸的是,在某些情况下(比如在与源代码控制等的协作环境中),上述情况经常发生得太频繁。显然,我的逻辑是有缺陷的 - 我真正需要的是“最后修改或复制”日期。这样的事情存在吗?

如果没有,那么有没有另一种方法来快速判断一个给定的文件是否有变化,并且具有合理的可靠性?

回答

4

你有没有想过在文件上运行MD5校验和并存储它们以便进行比较?如果你总是处理某个目录,这可能是可行的。

+0

是的,但是这是我的备用解决方案 - 我希望有一种方法可以确定给定的文件是否已更改(具有合理的可靠性),而无需读取文件本身。 – Justin 2010-09-30 06:33:40

9

你可能想看看使用FileSystemWatcher类。这个类允许你监视一个目录的变化,并在修改某些事件时触发一个事件。您的代码可以处理事件并处理文件。

从MSDN:

// Create a new FileSystemWatcher and set its properties. 
FileSystemWatcher watcher = new FileSystemWatcher(); 
watcher.Path = args[1]; 
/* Watch for changes in LastAccess and LastWrite times, and 
    the renaming of files or directories. */ 
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite 
    | NotifyFilters.FileName | NotifyFilters.DirectoryName; 
// Only watch text files. 
watcher.Filter = "*.txt"; 

// Add event handlers. 
watcher.Changed += new FileSystemEventHandler(OnChanged); 
watcher.Created += new FileSystemEventHandler(OnChanged); 
watcher.Deleted += new FileSystemEventHandler(OnChanged); 
watcher.Renamed += new RenamedEventHandler(OnRenamed); 
+0

麻烦的是,这个过程是一个批处理过程,所以不会一直运行。事实上,如果有问题的文件夹是映射的网络驱动器,那么*计算机*可能甚至没有运行。 – Justin 2010-09-30 06:43:15

+0

我知道经常扫描一个目录并不是最好的解决方案。很好的答案! – Nolonar 2014-01-24 12:13:15

0

你有没有考虑添加一个进程看你的目录呢?使用FileSystemWatcher?然后,您将从使用批处理流程和实时系统来监控文件。

3

您可以使用FileInfo类获取所需的更改信息(您可能已经在使用)。您需要检查文件的两个属性,分别是LastWriteTimeCreationTime。如果它们中的任何一个比您上次处理日期更高,则需要复制该文件。这是一个普遍的误解,认为CreationTime总是小于LastWriteTime。不是。如果一个文件被复制到另一个文件,新文件保留源的LastWriteTime,但CreationTime将是复制的时间。

+1

啊 - 太近了!这几乎可以工作,但不幸的是,如果你覆盖了一个文件,那么看起来创建时间就像创建* original *文件的时间一样。 – Justin 2010-09-30 07:07:45

+0

你用什么方法覆盖文件?因为如果文件被覆盖,其CreationTime将与之前相同,但它的'LastWriteTime'将会改变。其中一个属性必须改变。 – Yogesh 2010-09-30 07:11:47

+0

如果使用cmd.exe中的“复制”,则将目标文件“LastWriteTime”设置为源文件LWT,而不是更新为当前时间。 – snemarch 2010-09-30 08:03:41

0

正如您所观察到的,将文件复制到现有目标文件会保留现有文件的CreationTime,并将LastWriteTime设置为源文件的LastWriteTime,而不是执行复制时的当前系统时间。两种可能的解决方案:

  1. 做一个删除和复制,确保目标CreationTime将系统的当前时间。
  2. 检查文件的A rchived属性以及在处理时清除它。当复制source-> dest时,dest + A属性将被设置。
相关问题