进程无法访问文件,因为另一个进程正在使用该文件

本文关键字:文件 进程 因为 访问 另一个 | 更新日期: 2023-09-27 18:26:28

这是一个场景,我有一个应用程序,它每2秒覆盖一个xml文件。然后我有一个c#应用程序,它每1-2秒读取一次这个文件。这个过程运行得很好,但有时我会收到错误消息,说

进程无法访问文件,因为它被另一个进程使用

我正在使用xmldocument.load打开并读取xml文件。

我能做些什么来解决这个问题?我试过在不同的机器上运行,这是绝对随机的,因为在我的机器上,它在错误发生前运行了6个小时,在另一台机器上,

Coz我的c#程序将继续读取此文件,除非用户单击按钮停止数据记录过程

因为我希望程序继续运行,只要用户不停止它。请帮助

进程无法访问文件,因为另一个进程正在使用该文件

请告知您是否尝试过使用FileStream变量读取XmlDocument内容,该变量是使用指定的特殊构造函数使用适当的FileMode、FileAccess和FileShare参数实例化的。您可以使用load方法的实现来加载XmlDocument的内容,该方法以适当打开的文件流(对于写入和读取访问共享,反之亦然)作为参数。

请尝试使用以下代码写入文件:

XmlDocument xmlDocument = new XmlDocument();
using (FileStream fileStream = new FileStream("C:''test.xml", FileMode.Append, FileAccess.Write, FileShare.Read))
{
    xmlDocument.Load(fileStream);
}

以及以下用于从文件中读取的代码:

XmlDocument xmlDocument = new XmlDocument();
int attempts = 5;
Exception cannotReadException = null;
while (attempts > 0)
{
    try
    {
        using (FileStream fileStream = new FileStream("C:''test.xml", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            xmlDocument.Load(fileStream);
            attempts = 0;
        }
    }
    catch (Exception exception)
    {
        cannotReadException = exception;
        System.Threading.Thread.Sleep(100);
        attempts--;
    }
}
if (cannotReadException != null)
{
    throw cannotReadException;
}

当另一个应用程序写入同一个文件时,您无法从文件中读取,如果您同时开发了两个应用程序,我会重新编译真实的数据库,而不是XML文件。例如SQLite。

但如果您不想使用xml文件,您可以捕获XmlDocument.Load抛出的异常,并尝试再次读取,希望其他过程通过写入来完成

该文件有时仍被标记为操作系统正在使用、另一台计算机正在使用或病毒扫描程序正在使用,并且释放速度不够快,无法用于程序。您应该插入一个小的超时/延迟,或者使用try..捕获异常。。catch,并在稍有延迟后重试。

当您使用计时器时,您应该在处理文件时停止计时器,直到完成:

private void timer_Tick(object sender, EventArgs e)
{
  try
  {
    timer.Stop();
    //read write whatever ...
  }
  catch(){}  
  timer.start(); 
}

为了避免冲突,请这样重写:

  • 将新XML写入与旧XML位于相同位置的临时文件
  • 将新文件重命名为旧文件

在UNIX文件系统上,这将避免在写入过程中读取尝试失败的问题。不确定窗口,但应该可以。

为了扩展其他人的建议,下面是一个如何使用try-catch块来解决冲突的示例:

private XmlDocument OpenXML(string filename, int retryCount = 0)
{
    XmlDocument retval = new XmlDocument();
    try
    {
        retval.Load(filename);
    }
    catch
    {
        if (retryCount < 5)
        {
            retval = OpenXML(filename, retryCount + 1);
        }
        else
        {
            return null;
        }
    }
    return retval;
}

在catch中,如果需要,可以添加暂停,或者增加重试次数/在达到最大尝试次数时以不同的方式处理。

如前所述,您可以实现一种简单的等待-x-(毫)秒并重试的方法。

如果您在Windows上,并且可以访问这两个程序的源代码,则可以使用本机Win32函数创建一个信号量来调节对文件的访问。有关详细信息,请参阅本页。