C# 未使用System.IO.FileSystemWatcher功能处理IOException
基本上,我要做的是观察放入具有特定文件扩展名(*.req)的文件夹中的新文件,因此我开始使用System.IO.FileSystemWatcher功能进行设置。因此,在我启动程序后,我只需将一组*.req文件复制到我关注的文件夹中,它们第一次似乎运行良好,没有任何错误。这些文件随后被重命名、处理,然后被删除。随后,我将重新复制相同的*.req文件,现在这一次,它抛出了一个IOException is unhandled错误,详细如下:C# 未使用System.IO.FileSystemWatcher功能处理IOException,c#,filesystemwatcher,C#,Filesystemwatcher,基本上,我要做的是观察放入具有特定文件扩展名(*.req)的文件夹中的新文件,因此我开始使用System.IO.FileSystemWatcher功能进行设置。因此,在我启动程序后,我只需将一组*.req文件复制到我关注的文件夹中,它们第一次似乎运行良好,没有任何错误。这些文件随后被重命名、处理,然后被删除。随后,我将重新复制相同的*.req文件,现在这一次,它抛出了一个IOException is unhandled错误,详细如下: System.IO.IOException was
System.IO.IOException was unhandled
HResult=-2147024864
Message=The process cannot access the file 'C:\accucom\reqdir\hcd - Copy (2).req' because it is being used by another process.
Source=mscorlib
StackTrace:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)
at System.IO.File.Copy(String sourceFileName, String destFileName)
at CollectV2.CollectV2.OnChanged(Object source, FileSystemEventArgs e) in C:\accucom\CollectV2\CollectV2.cs:line 375
at System.IO.FileSystemWatcher.OnCreated(FileSystemEventArgs e)
at System.IO.FileSystemWatcher.NotifyFileSystemEventArgs(Int32 action, String name)
at System.IO.FileSystemWatcher.CompletionStatusChanged(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* overlappedPointer)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
InnerException:
下面是我正在使用的代码片段,我想知道我在这里可能缺少什么:
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = GlobalVars.REQpath;
// Only watch *.req files.
watcher.Filter = "*.req";
watcher.Created += new FileSystemEventHandler(OnChanged);
// Begin watching.
watcher.EnableRaisingEvents = true;
// Wait for the user to quit the program.
Console.WriteLine("Press \'q\' to quit the sample.");
while (Console.Read() != 'q') ;
// Define the event handlers.
private static void OnChanged(object source, FileSystemEventArgs e)
{
// Specify what is done when a file is changed, created, or deleted.
Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType);
string rqfile = e.FullPath.Replace(".req", ".re0");
//System.IO.File.Delete(rqfile);
System.IO.File.Copy(e.FullPath, rqfile);
System.IO.File.Delete(e.FullPath);
ThreadPool.QueueUserWorkItem(wcbdoRequestFile, rqfile);
}
我认为问题在于这些方面:
System.IO.File.Copy(e.FullPath, rqfile);
System.IO.File.Delete(e.FullPath);
我猜问题在于,当更改文件的过程仍然打开文件时,您会响应正在更改的文件
理想的解决方案是让正在更改文件的程序在完成并关闭文件时通知您的程序
如果做不到这一点,我找到的唯一方法就是反复尝试复制/删除操作,直到成功,每次尝试之间都要等待一段时间。这当然不是很好,但如果无法与其他程序通信,这可能是您所能做的一切。我最终使用了以下代码,避免了出错,但仍然不理解为什么它必须等待某个进程完成:
System.IO.File.Delete(rqfile);
while (true) {
try
{
System.IO.File.Copy(e.FullPath, rqfile);
break;
}
catch { }
}
System.IO.File.Delete(e.FullPath);
我最初的方法是使用以下命令继续读取文件夹目录中的任何.req文件,中间有一个sleep(250):files=System.IO.directory.GetFiles(GlobalVars.REQpath,“.req”,SearchOption.TopDirectoryOnly);我遇到的问题是路径位于一个网络文件夹中,客户端程序可以将其放置在该文件夹中,但我注意到,在这个专用服务器实际使用此方法查看文件之前,可能需要5-6秒的时间,因此,如果可能的话,我正在寻找一种更快的方法,并且最终必须能够正常工作。