【问题标题】:Windows: How to determine if a file has been modified since a given dateWindows:如何确定文件自给定日期以来是否已被修改
【发布时间】:2023-03-08 20:30:01
【问题描述】:

我有一个实用程序可以处理目录中的一组文件-该过程相对较慢(并且文件很多),因此我尝试通过仅处理具有晚于最后处理日期的“最后修改”。

通常这很好用,但是我发现复制文件不会更改上次修改日期,因此存在多种涉及复制文件的情况,其中某些已更改的文件会被进程跳过,例如:

  1. 用户在 9:00 处理目录。
  2. 然后从该目录复制一个文件并对其进行修改,使其最后修改日期为 9:30
  3. 然后在 10:00 再次处理该目录
  4. 修改后的文件随后会在 10:30 复制回目录中
  5. 终于在11:00再次处理目录

由于给定文件的修改日期是 9:30,并且该目录的最后处理时间是 10:00,因此不应该跳过该文件。

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

如果做不到这一点,是否有另一种方法可以以合理的可靠性快速确定给定文件是否已更改?

【问题讨论】:

    标签: c# last-modified


    【解决方案1】:

    您可能想看看使用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);
    

    【讨论】:

    • 问题是这个过程是一个批处理过程,所以不会一直运行。事实上,如果有问题的文件夹是一个映射的网络驱动器,那么 计算机 甚至可能都没有运行。
    • 我知道不断扫描目录并不是最好的解决方案。很好的答案!
    【解决方案2】:

    您是否考虑过对文件运行 MD5 校验和并稍后存储它们以进行比较?如果您总是处理某个目录,这可能是可行的。

    【讨论】:

    • 是的,但是这是我的后备解决方案 - 我希望有一种方法可以确定给定文件是否已更改(具有合理的可靠性),而无需读取文件本身。
    【解决方案3】:

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

    【讨论】:

    • 啊——这么近!这几乎可行,但不幸的是,如果您要覆盖文件,那么创建时间看起来就像创建 original 文件的时间一样。
    • 你用什么方法覆盖文件?因为如果一个文件被覆盖,它的 CreationTime 将和以前一样,但它的LastWriteTime 会改变。其中一项属性必须更改。
    • 如果使用 cmd.exe 中的“复制”,则目标文件LastWriteTime 设置为源文件 LWT,而不是更新到当前时间。
    • 再次阅读答案。我已经说过了……“如果将文件复制到另一个文件,则新文件将保留源的 LastWriteTime 但 CreationTime 将是复制的时间。”您用来复制的内容、资源管理器或命令提示符或 System.IO .FileCopy 方法几乎无关紧要。
    【解决方案4】:

    您是否考虑过添加一个进程来监视您的目录?使用 FileSystemWatcher?然后,您不再使用批处理和实时系统来监控您的文件。

    【讨论】:

      【解决方案5】:

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

      1. 执行删除和复制,确保目标 CreationTime 将是系统的当前时间。
      2. 还要检查文件的 Archived 属性,并在处理时将其清除。复制source->dest时,会设置dest+A属性。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-07
        • 1970-01-01
        相关资源
        最近更新 更多