【问题标题】:The process cannot access the file because it is being used by another process. Unexpected error该进程无法访问该文件,因为它正被另一个进程使用。意外的错误
【发布时间】:2015-07-13 16:55:53
【问题描述】:

我正在使用 c# 使用此代码进行 FTP 文件上传

while(true)
{
    if(condition == true)
    {
        Process[] proc = Process.GetProcessName("ThirdPartyApp");
        if(proc.Length <0 )
        {
            var file = Process.GetProcess().Where(pr=>pr.ProcessName == "ThirdPartyApp")
            foreach(var process in file)
            {
                process.kill(); // Third party application stopped
            }
            if(File.Exists(filename))
            {
               using (System.Net.WebClient client = new System.Net.WebClient())
               {
                 client.Credentials = new System.Net.NetworkCredential("username", "password");
                 client.UploadFile(ftpServer  + new FileInfo(filename).Name, "STOR", filename);
               }
               File.Delete(filename);
               Process.Start("ThirdPartyApp");
            }
       }
    }
}

我的程序持续运行。在指定时间,它将文件上传到服务器。我的程序启动后,第一次成功将文件上传到服务器,但在另一个时间间隔,第二次,它给出了这个异常。

我不明白为什么它在第一次循环运行时出错,但为什么它在第二次循环时出错。

The process cannot access the file 'E:\TYV.csv' because it is being used by another process.

删除文件后,会立即创建一个新文件。在第二次运行时,哪个进程正在使用该文件?是我自己的应用吗?

为什么第一次没有锁定?

谢谢

【问题讨论】:

  • 被投诉的文件是在客户端还是服务器上?
  • 它在客户端上,我在服务器上发送它。第三方应用程序正在创建它。在上传之前,我先杀死第三方应用程序然后上传,然后再次启动第三方应用程序。
  • 如果您可以访问服务器,您可以使用解锁器查看哪个进程正在锁定文件。 filehippo.com/download_unlocker。但我认为这是您的申请。
  • 你为什么使用while(true)?尝试将上传代码放在不同的方法中,而不是在 while 循环中,并使用 Timer 而不是 while 循环,始终为真。
  • 我不允许在服务器上上传任何软件。此问题仅出现在服务器上,而不出现在我的系统上。定时器也有同样的问题。

标签: c#


【解决方案1】:

如果文件被锁定,则不会按照 cmets 中的建议更改循环。确保您的应用程序正在锁定文件。这可能意味着您正在尝试在第三方释放 ts 之前或在写入完成之前上传文件(这可能发生在缓冲 IO 中)。

如果您无权访问第三方应用来检查它在做什么(并在必要时进行更改),您可以执行以下操作:

第一个例程检查文件是否被锁定(取自这里:Is there a way to check if a file is in use?

//routine to check if the file is locked
protected virtual bool IsFileLocked(FileInfo file)
{
    FileStream stream = null;

    try
    {
        stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
    }
    catch (IOException)
    {
        //the file is unavailable because it is:
        //still being written to
        //or being processed by another thread
        //or does not exist (has already been processed)
        return true;
    }
    finally
    {
        if (stream != null)
            stream.Close();
    }

    //file is not locked
    return false;
}

public void SendFile(string filename, int maxTries)
{
    bool done;
    while(true)
    {
        if(condition == true)
        {
            if(!IsFileLocked(filename))
            {
                Process[] processes = Process.GetProcessByName("ThirdPartyApp");
                foreach (var proc in processes)
                    proc.Kill();

                using (System.Net.WebClient client = new System.Net.WebClient())
                {
                    client.Credentials = new System.Net.NetworkCredential("username", "password");
                    int count = 0;
                    done = false;
                    while (count < maxTries || !done)
                    {
                        try
                        {
                            client.UploadFile(ftpServer  + new FileInfo(filename).Name, "STOR", filename);
                            done = true;
                        }
                        catch(Exception ex)
                        {
                            System.Threading.Thread.Sleep(5000);
                            count++;
                        }
                    }
                    if (!done)
                    {
                        //handle the error
                    }
                }

                File.Delete(filename);
                Process.Start("ThirdPartyApp");
            }
        }
    }
}

如果是临时储物柜的问题,这个可以帮你解决。 但请注意,如果您在第三方释放文件之前将其杀死,并且 File.Exist 会给您造成进程已完成工作的错误印象,您仍然会获得文件中的锁定。

另一点是检查文件是否被锁定也可能失败,如果在检查之后“ThirdPartyApp”锁定文件并且您在应用程序发布之前杀死应用程序。

所以,对我来说,最好的答案是使用 thsi 代码并尝试打开文件(自己锁定)。如果可以(没有例外),请使用打开的流发送到 FTP。完成后,关闭它,删除文件并再次运行 ThirdApp。

编辑:添加代码以查看文件是否被锁定,只有在没有删除 ThirdPartyApp 的情况下才执行其余代码。

【讨论】:

  • 我已经编辑了上面的代码,显示了实际的代码。如前所述,我在将文件上传到服务器之前杀死了 ThirdPartyApp。此外,时间每秒都在运行,即循环每秒执行一次。
  • 正如我所说,如果在文件准备好或应用程序发布之前终止进程,则终止创建您尝试上传的文件的进程很有可能导致文件被锁定文件。完成此操作的频率(1 秒)将进一步提高这些可能性。
  • 好的,那么为什么它在第一次运行循环时不锁定文件,但只有在第一次运行后,即第二次或第三次运行相同的代码,它给出了异常。如果按照您的逻辑进行,那么它在第一次运行时也会出现问题!!!!!!
  • 不一定。发生这种情况的原因有很多。例如:第一次,文件已经存在,因为 ThirdPartApp 已经在运行并在您的应用程序启动时完成了它的工作,而第二次,当您简单地杀死它时它正在处理文件。我还注意到您在检查文件是否存在之前杀死了该应用程序。我将编辑我的答案,为您提供一些关于如何验证您是否可以做您想做的事情的“见解”(将文件发送到 FTP)。
  • 请看我最后的答案。我真的认为你应该打开文件并将流发送到 FTP。如果它被锁定,打开它会引发异常,然后您只需忽略并在下一个周期重试。如果它打开,它将锁定文件(使用正确的模式),然后你可以杀死应用程序,因为文件将在你的控制之下。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-10
相关资源
最近更新 更多