【问题标题】:How to determine when files are done copying for further processing?如何确定文件何时完成复制以进行进一步处理?
【发布时间】:2011-06-25 20:44:39
【问题描述】:

好吧,开始这只是针对 Windows,我更喜欢在 .NET 上使用 C++,但我不反对boost::filesystem,尽管如果可以避免使用直接的 Windows API,我更喜欢.

现在的场景是另一台机器上的应用程序我无法更改,它将在机器上的特定目录中创建文件,我需要对其进行备份并进行一些额外的处理。目前我制作了一个小应用程序,它将使用FindFirstChangeNotificationFindNextChangeNotification windows API 监听目标目录中的更改通知。

问题是,虽然我可以在目录中创建新文件、修改文件、大小更改等时收到通知,但它只通知一次,并没有具体告诉我哪些文件。我也看过ReadDirectoryChangesW,但那里的情况相同,只是我可以获得更具体的信息。

现在我可以扫描目录并尝试获取锁或打开文件以确定与上次通知相比具体发生了什么变化以及它们是否可用于进一步使用但在复制大文件的情况下我发现这是'不够好,因为文件还没有准备好被操作,而且在第一次之后我不会收到任何其他通知,所以没有办法知道它何时实际完成复制,除非在第一次通知之后我不断尝试获取锁直到成功。

我能想到的唯一另一件事就是拥有某种 end 令牌文件,但由于我无法控制在第一个创建文件的应用程序我不知道该怎么做,但仍然不理想。

有什么建议吗?

【问题讨论】:

    标签: c++ windows file filesystems


    【解决方案1】:

    这是一个相当普遍的问题,而且没有一个简单的答案。当您无法在远程更改事物时,获取锁是最佳选择之一。我见过的另一个方法是每隔一段时间观察文件,直到大小在一两个时间间隔内没有变化。

    其他策略包括在主文件完成时写入一个无字节文件作为触发器,然后写入临时目录,然后将完整文件移动到真正的目的地。但要可靠,必须是控制它的发送者。作为接收者,您只能查看目录并等待文件处理完毕。

    【讨论】:

    • 我曾短暂地玩过文件增长超时的想法,但它似乎比锁定请求更糟糕。也许我天真地乐观地认为有一个不涉及轮询的解决方案。
    • 问题是本地操作系统无法区分成功的文件结束与放弃或中断的副本之间的区别,因此它甚至不会尝试。即使轮询锁定方法也不是万无一失的,因为中断的副本将导致丢失锁定,并且当它恢复时文件可能已经备份。由于 WMQ FTE 是我专攻的产品之一,因此我在许多平台上看到了很多。事实证明这是一个不平凡的问题。
    • 这也是一个很好的观点,我什至没有想到这种可能性。
    • +1 表示无字节信号文件策略和复制然后移动策略。两者在批处理/shell 脚本中都很常见。
    【解决方案2】:

    看起来 ReadDirectoryChangesW 将是您的最佳选择。对于每个文件复制操作,您应该收到 FILE_ACTION_ADDED 后跟一堆 FILE_ACTION_MODIFIED 通知。在最后一个 FILE_ACTION_MODIFIED 通知中,文件不应再被复制过程锁定。因此,如果您在复制的每个 FILE_ACTION_MODIFIED 之后尝试获取锁,它应该会失败,直到复制完成。这不是一个特别优雅的解决方案,但文件复制完成时似乎没有任何通知可用。

    【讨论】:

    • 在我的测试中,至少在Windows 7中,问题似乎是文件系统的缓存机制。在FILE_NOTIFY_CHANGE_CREATION 之后不久,我只收到了一个FILE_NOTIFY_CHANGE_LAST_WRITE。即使副本不完整,它似乎也以完整大小创建目标文件,因此也只有一个 FILE_NOTIFY_CHANGE_SIZE 触发。我可能需要创建一个工作线程来调用 ReadDirectoryChangesW 以避免丢失通知,但是这个操作需要多长时间,即使使用当前的实现,我也希望得到多个。
    • @AJG85 您的观察是正确的,首先在复制期间设置文件大小(至少由资源管理器设置),然后写入数据。
    【解决方案3】:

    您可以在文件关闭后处理数据,对吗?所以任务是跟踪文件何时关闭。这可以使用文件系统过滤器驱动程序来完成。您可以自己编写,也可以使用我们的CallbackFilter 产品。

    【讨论】:

    • 您是否有包含有关文件系统过滤器驱动程序的更多信息的参考链接,以便我确定这是否值得实施?这听起来像是拦截系统内部,因此超出了该项目时间限制的工作范围。
    • AJG85 确实如果您想实现自己的过滤器,则需要几个月的工作。以下是有关过滤器的信息:microsoft.com/whdc/driver/filterdrv/default.mspx
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 2017-09-09
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多