如何检测文件夹是否已经复制完成?

3
在我的项目中,我有一个工作文件夹。如果我们从其他地方复制文件或文件夹到这个文件夹,我需要检测复制是否已经完成。之后,我将处理这个工作文件夹中的文件。
FileSystemWatcher theWatcher = new FileSystemWatcher(workingFolder);
theWatcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite |
                          NotifyFilters.FileName | NotifyFilters.DirectoryName |
                          NotifyFilters.Size;
theWatcher.IncludeSubdirectories = true;
theWatcher.Created += OnFolderChanged;
theWatcher.EnableRaisingEvents = true;

每当文件复制时,OnFolderChanged事件将被触发。因此,我首先尝试获取2个文件复制之间的时间差,但由于网络速度和文件大小的影响,时间差很难确定。我也尝试了在目录中查找复制进程是否正在进行的方法,但即使在复制过程中,令牌文件仍然可以被打开。

有没有好的方法来处理这个问题?


我们需要更多的信息。你知道目标文件夹中有多少个文件吗?这些文件是使用你的程序复制的吗?也许在目标文件夹末尾复制一个额外的空文件? - VladL
文件是如何被复制的?FileSystemWatcher无法知道复制模块是否还会复制更多的文件。 - Miserable Variable
不,源文件或文件夹可以来自任何地方。我们事先不知道。它们是通过标准的文件夹/文件复制进行复制,而不是通过我们的程序。 - user1424258
这就是为什么我一开始想要监控工作文件夹状态的原因。 - user1424258
如果你无法控制复制过程,那么你会遇到很大的麻烦。也许可以尝试钩入进程监视器使用的任何进程,并使用阈值来确定目标进程何时不再读取文件?我的意思是这是最不专业的方法,可能甚至不起作用,但如果没有其他办法,这是一个想法。 - devshorts
2个回答

2
您无法通过 FileSystemWatcher 来反向工程化您不了解的进程操作。有许多可能的故障模式,例如用户使用资源管理器复制文件时显示对话框,因为目标文件已存在。此时用户可能离开一会儿。
您应该永远不要做出任何关于正在进行的操作的假设。当您收到通知时,任意地开始一个一分钟的计时器,并在收到另一个通知时重新启动它。当计时器滴答作响时,您就有了某些理由猜测复制操作已完成。只要确保猜错时不会成问题。

我之前遇到的问题是我没有在OnFolderChanged事件中调用timer.stop()和timer.start()。但我们确实需要设置一个合理的阈值。再次感谢。 - user1424258

0

如果您可以控制复制文件/文件夹的过程,那么在完成复制时可以将后缀(.complete)附加到文件/文件夹,并设置文件系统监视器仅响应具有.complete扩展名的文件/文件夹。

更新-由于您无法控制复制的文件/文件夹名称,因此我会在FolderChaged方法中使用异常处理。我假设您正在该方法中对文件/文件夹进行某些处理,并且当您尝试访问未完成复制的文件/文件夹时,您将获得某种System.IO异常。

我也遇到了FSW的这个问题,并通过捕获异常、暂停几秒钟,然后再次尝试访问文件来处理它。我将这个逻辑放在一个循环中,该循环将在10秒内重试5次访问文件。如果我们在5次尝试后仍无法处理文件,则抛出异常并启用标准错误处理。

当然,仍然存在一个开放性问题,即您的适当循环参数是什么,如果达到这些参数的限制,您如何处理失败?


我们无法控制这些文件。 - user1424258
请看我上面的更新。我发布了一种解决此问题的方法。不确定它是否适用于您。希望这有所帮助! - pmartin
当复制正在进行时,我可以访问工作文件夹,并更新其中的文件。因此,System.IO异常可能对我无效。 - user1424258

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接