将多个文件添加到目录中时,FileSystemWatcher的文件访问错误
将多个文件放入监视目录时,FileSystemWatcher出现问题。我想在将文件放入目录后立即对其进行解析。通常,第一个文件可以很好地解析,但是将第二个文件添加到目录中会导致访问问题。有时,第一个文件甚至不会解析。只有一个应用程序正在运行并监视此目录。最终,此过程将在多台计算机上运行,并且它们将监视共享目录,但是当将数据导入数据库时,只有一台服务器可以解析每个文件,并且没有主键。
这是FileSystemWatcher代码:
public void Run() { FileSystemWatcher watcher = new FileSystemWatcher("C:\\temp");
watcher.NotifyFilter = NotifyFilters.FileName;
watcher.Filter = "*.txt";
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.EnableRaisingEvents = true;
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
}
然后解析文件的方法:
private void OnChanged(object source, FileSystemEventArgs e) { string line = null;
try {
using (FileStream fs = new FileStream(e.FullPath, FileMode.Open, FileAccess.Read, FileShare.None)) {
using (StreamReader sr = new StreamReader(fs)) {
while (sr.EndOfStream == false) {
line = sr.ReadLine();
//parse the line and insert into the database
}
}
}
}
catch (IOException ioe) {
Console.WriteLine("OnChanged: Caught Exception reading file [{0}]", ioe.ToString());
}
移动第二个文件时,它正在捕获
System.IO.IOException:该进程无法访问文件’C:\ Temp \ TestFile.txt’,因为它正在被另一个进程使用。
如果它在多台计算机上运行,我希望看到此错误,但是目前仅在一台服务器上运行。使用该文件不应再有其他进程-
我创建了它们,并在应用程序运行时将它们复制到目录中。
这是设置FileSystemWatcher的正确方法吗?如何查看此文件的锁?为什么不解析两个文件-
我必须关闭FileStream吗?我想保留FileShare.None选项,因为我只希望一台服务器解析该文件-到达该文件的服务器首先对其进行解析。
回答:
这种方法的典型问题是在触发事件时仍在复制文件。显然,您会得到一个例外,因为文件在复制过程中被锁定。大文件特别有可能发生异常。
解决方法是,您可以先复制文件,然后重命名文件并侦听重命名事件。
或者另一个选择是进行while循环,以检查是否可以使用写访问权限打开文件。如果可以,您将知道复制已完成。C#代码可能看起来像这样(在生产系统中,您可能希望具有最大的重试次数或超时次数,而不是while(true)
):
/// <summary>/// Waits until a file can be opened with write permission
/// </summary>
public static void WaitReady(string fileName)
{
while (true)
{
try
{
using (Stream stream = System.IO.File.Open(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
if (stream != null)
{
System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} ready.", fileName));
break;
}
}
}
catch (FileNotFoundException ex)
{
System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} not yet ready ({1})", fileName, ex.Message));
}
catch (IOException ex)
{
System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} not yet ready ({1})", fileName, ex.Message));
}
catch (UnauthorizedAccessException ex)
{
System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} not yet ready ({1})", fileName, ex.Message));
}
Thread.Sleep(500);
}
}
另一种方法是在复制完成后在文件夹中放置一个小的触发器文件。您的FileSystemWatcher将仅侦听触发器文件。
以上是 将多个文件添加到目录中时,FileSystemWatcher的文件访问错误 的全部内容, 来源链接: utcz.com/qa/423202.html