C#FileSystemWatcher,如何知道文件完全复制到watch文件夹类,并附上其Created事件到文件夹。我必须对此事件采取行动(即将文件复制到另一个位置)。当我将大尺寸放入附加的监视文件夹时,即使文件复制过程仍未完成,事件也会立即触发。我不想通过file.open方法检查它。有没有办法在我的活动开始之前通知我的文件复制过程已完成。令人失望的是,FileSystemWatcher(以及底层的ReadDirectoryChangesWAPI)根本无法在创建新文件时得到通知。到目前为止我遇到的最好和最安全的方法(并且不依赖计时器)是这样的:在接收到Created事件时,启动一个线程来检查文件是否仍处于锁定状态(使用适当的重试间隔)和最大重试次数)。检查文件是否被锁定的唯一方法是尝试以独占访问方式打开它:如果成功(不抛出IOException),文件复制完成并且您的线程可以引发适当的事件(例如FileCopyCompleted)。我遇到了完全相同的问题并以这种方式解决了它:设置一个FileSystemWatcher以在创建文件和修改文件时发出通知。通知时:如果没有为此文件名设置计时器(见下文),请将计时器设置为以适当的时间间隔到期(我通常使用1秒)。b.如果为此文件名设置了计时器,请取消计时器并设置新的计时器以相同的时间间隔到期。当计时器到期时,您知道有问题的文件已创建或修改,并且在该时间间隔内未被触及。这意味着复制/修改可能已经完成,您现在可以处理它。您可以收听修改后的事件,并启动计时器。如果再次引发修改后的事件,请重置计时器。当计时器达到某个值而没有引发修改事件时,您可以尝试执行复制。我订阅了Changed-和Renamed-events,并尝试在每个Changed-event上重命名文件,捕获IOExceptions。如果重命名成功,则复制完成,重命名事件仅触发一次。FileSystemWatcher有三个问题,第一个是它可以发送重复创建的事件,所以你可以检查:this.watcher.Created+=(s,e)=>{if(!this.seen.ContainsKey(e.FullPath)||(DateTime.Now-this.seen[e.FullPath])>this.seenInterval){this.seen[e.FullPath]=DateTime.Now;ThreadPool.QueueUserWorkItem(this.WaitForCreatingProcessToCloseFileThenDoStuff,e.FullPath);}};其中this.seen是Dictionary,this.seenInterval是TimeSpan。接下来,您必须等待文件创建者完成写入(问题中提出的问题)。第三,您必须小心,因为有时文件创建事件会在文件打开之前抛出,但不会给您FileNotFoundException,但它也可以被删除,然后您也可以让它也给一个FileNotFoundException。privatevoidWaitForCreatingProcessToCloseFileThenDoStuff(objectthreadContext){//确保刚刚找到的文件已完成//通过反复尝试打开它//以进行独占访问来写入。变种路径=(字符串)线程上下文;DateTime开始=DateTime.Now;日期时间lastLengthChange=DateTime.Now;长lastLength=0;varnoGrowthLimit=newTimeSpan(0,5,0);varnotFoundLimit=newTimeSpan(0,0,1);for(inttries=0;;++tries){try{using(varfileStream=newFileStream(path,FileMode.Open,FileAccess.ReadWrite,FileShare.None)){//做事情}break;}catch(FileNotFoundException){//有时文件在出现之前就出现了。if(DateTime.Now-started>notFoundLimit){//现在应该在那里break;}}catch(IOExceptionex){//严重性、客户和代码中的掩码varhr=(int)(ex.HResult&0xA000FFFF);if(hr!=0x80000020&&hr!=0x80000021){//不是共享违规或锁违规throw;}}try{varfi=newFileInfo(path);如果(fi.Length>lastLength){lastLength=fi.Length;lastLengthChange=DateTime.Now;}}catch(Exceptionex){}//仍然锁定if(DateTime.Now-lastLengthChange>noGrowthLimit){//5分钟,仍然锁定,没有growth.break;}Thread.Sleep(111);}当然,你可以为这段代码设置自己的超时时间,留出足够的时间挂起5分钟。如果请求,真实代码也有一个退出线程的标志。尝试设置过滤器myWatcher.NotifyFilter=NotifyFilters.LastAccess|NotifyFilters.LastWrite;这个答案有点晚了,但如果可能的话,我会让源进程在大文件或文件之后复制一个小标记文件,并在其上使用FileWatcher。以上就是C#学习教程:C#FileSystemWatcher,如何知道文件是否完整复制到watch文件夹分享所有内容,如果对你有用还需要了解更多C#学习教程,希望各位多多关注——本文来自网络合集,不代表立场,如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
