将多个文件添加到目录中时,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

回到顶部