c#中的另一个进程正在使用该文件

时间:2016-01-28 09:36:28

标签: c# asp.net filestream

我正在尝试删除C#中的文件,但是我收到的消息是该文件是从另一个进程中使用的。我想要做的是检查文件是否存在并关闭它。我正在使用以下函数来检查文件是否已打开:

public static bool IsFileInUse(string path)
    {
        if (string.IsNullOrEmpty(path))
            throw new ArgumentException("'path' cannot be null or empty.", "path");

        try
        {
            using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read)) { }
        }
        catch (IOException)
        {
            return true;
        }

        return false;
}

我正在尝试使用该文件关闭它:

bool checking = IsFileInUse(file );
File.Create(file ).Close();
if (File.Exists(file))
{
       File.Delete(file );
}

我在File.Create行遇到了问题,我收到了消息:

  

另一个进程正在使用该文件。

编辑:我正在尝试使用锁定方法来删除文件。我想删除锁定语句中的文件?我如何正确使用锁定声明?

3 个答案:

答案 0 :(得分:4)

为什么假设如果正在使用文件而写入操作不会导致读取操作失败? File.Create()将在新FileStream()失败之前完全失败......

另见IOException: The process cannot access the file 'file path' because it is being used by another process

请注意,如果其他进程没有独占打开该文件,则检查将失败(检查FileShare枚举):文件可能会打开以进行共享读取,写入,有时甚至可以删除(例如,可以同时读取但不能写入,但是其他进程可能会让你删除该文件...)。

关闭一个打开的文件可能会对其他进程造成破坏,它可能崩溃,很好地处理问题或者......其他任何事情(默默地忽略该错误并产生随机输出,再次打开文件等等...... )是否有可能在C#中做到这一点?是的,有一些P / Invoke ......

1)让我们找到您要解锁的文件的句柄。使用NtQuerySystemInformation()并枚举所有句柄,直到找到引用该文件的句柄。

2)使用DuplicateHandle()复制该句柄在您自己的流程中有效。

3)关闭只创建指定DUPLICATE_CLOSE_SOURCE的句柄,它将关闭你的句柄和原始句柄(当然,如果你的进程有足够的权限)。

4)检查文件是否真的关闭再次调用NtQuerySystemInformation(),如果没有,则可能需要直接关闭其父进程。

答案 1 :(得分:2)

如果文件存在,则无需检查,只需尝试删除

https://msdn.microsoft.com/en-us/library/system.io.file.delete(v=vs.110).aspx

  

如果要删除的文件不存在,则不会抛出任何异常。

尝试检查异常

  try {
    File.Delete(file);
  }
  catch (IOException) {
    // File in use and can't be deleted; no permission etc.
  }

答案 2 :(得分:0)

在您的代码中,您不会对IsFileInUse结果执行任何操作。

File.Create(file ).Close();也不会关闭由其他进程打开的文件。您需要关闭打开文件的进程,如果它是您自己的应用程序,请在尝试删除文件之前关闭文件句柄。

bool checking = IsFileInUse(file );
File.Create(file ).Close();
if (!checking) 
{
     if (File.Exists(file))
     {
            File.Delete(file );
     }
}