文件正在被其他程序使用异常

3

我有两个C# .NET应用程序:

  • 一个应用程序(称为App1)将数据写入XML文件。
  • 第二个应用程序(称之为App2)从同一XML文件中读取数据并更新自身。

App2不断监视XML文件的更改,我使用FileSystemWatcher进行监控。

一旦App1完成对文件的写入,App2就会读取更改。

我确保App2仅以读取访问权限读取XML文件,但有时App1仍会抛出异常:

"The process cannot access the file 'C:\xmlFile' because it is being used by another process"。以下是我的App2代码片段,用于读取该文件。

这是我的代码:

using (var stream = File.Open(filePath,FileMode.Open,FileAccess.Read))
{
    using (XmlReader reader = XmlReader.Create(stream))
    {
        while (reader.Read())
        {
            // Only detect start elements.
            if (reader.IsStartElement())
            {
                switch (reader.Name)
                {
                    case "Component":
                        fileElements.ComponentName = reader["Name"];
                        fileElements.DateRun = reader["DateRun"];
                        fileElements.Passed = reader["Passed"];
                        break;
                }
            }
        }

        if (filePath.ToLower().Contains("ebsserver"))
        {
            UpdateDataTable1(fileElements);
        }
        else if (filePath.ToLower().Contains("ebsui"))
        {
            UpdateDataTable2(fileElements);
        }
        else
        {
            UpdateDataTable3(fileElements);
        }
    }
}

我该如何解决这个问题?

仅仅因为你指定了只读,就不意味着它可以打开文件,如果另一个进程拥有它的话。在应用程序2能够打开该文件之前,你需要验证应用程序1是否已经关闭该文件。由于应用程序1可能在关闭之前将其刷新到文件并引发文件更改通知,所以完全有可能会遇到冲突。 - Ron Beyer
文件访问不影响共享,它只影响您的进程权限,而不影响其他进程。两个应用程序都需要使用适当的共享权限打开文件。App2看起来应该使用FileShare.ReadWrite。默认值为FileShare.None。 - Mike Zboray
2个回答

1

在阅读应用程序中,您必须使用 FileShare.ReadWrite 来表明在打开文件时不会有锁定。这是与文本编辑器相同的机制,它们打开被写入的文件。

File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)

默认情况下是None。这就是为什么会出现此异常的原因。最近我自己也遇到了这个问题,当我尝试读取正在不断写入的日志文件时。之后,它完美地工作了。 - bytecode77
谢谢您的回复。我会尝试并告诉您结果。我每24小时才会遇到这个问题。我会让它在这个更改下运行一晚上并进行验证。 - marak

0

你在 File.Open 方法中缺少了 FileShare 参数

    using (var stream = File.Open(filePath,FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    using (XmlReader reader = XmlReader.Create(stream))
    {
        while (reader.Read())
        {
            // Only detect start elements.
            if (!reader.IsStartElement())
            {
                continue;
            }

            if (reader.Name != "Component")
            {
                continue;
            }

            fileElements.ComponentName  = reader["Name"];
            fileElements.DateRun        = reader["DateRun"];
            fileElements.Passed         = reader["Passed"];
       }

       if (filePath.ToLower().Contains("ebsserver"))
       {
           UpdateDataTable1(fileElements);
       }
       else if (filePath.ToLower().Contains("ebsui"))
       {
           UpdateDataTable2(fileElements);
       }
       else
       {
           UpdateDataTable3(fileElements);
       }
   }

我同意并通常会删除它,但这不是因为答案还向OP演示如何保持他的代码干净整洁,我已经对其进行了清理,使其更易读,并删除了不必要的代码部分,如果您比较这两个版本,您就会明白我的意思。话虽如此,你确实比我先发帖,所以我给你点赞。 - Aydin
说实话,我认为在C#中垂直对齐代码并不是一个很好的做法,因为Visual Studio会自动格式化。 - bytecode77
我不确定我理解你的意思,我在谈论嵌套的if语句和不必要的switch语句。 - Aydin
这更多或少是个人口味问题。我更喜欢将两个方程放入一个 if 中。但是,下面垂直对齐的三行将由 Visual Studio 格式化为 OP 中所看到的样子。 - bytecode77

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