【问题标题】:File is being used by another process in c#c#中的另一个进程正在使用文件
【发布时间】:2016-01-28 09:36:27
【问题描述】:

我正在尝试在 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 行中遇到问题,我收到了消息:

文件正被另一个进程使用。

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

【问题讨论】:

  • 您无法通过任何直接的方法关闭由其他进程打开的文件。
  • 因此我应该终止进程以关闭文件,对吧?
  • 那是你的申请吗?如果是,那么您可以发送消息以释放它或使用进程间锁
  • 其他使用它的进程是什么?是您的应用本身吗?
  • 你可以找到很多关于锁、多线程的文章,这就是msdn所说的锁,msdn.microsoft.com/en-us/library/c5kehkcz.aspx

标签: c# asp.net filestream


【解决方案1】:

为什么你认为如果文件正在使用,读操作会失败,而写操作不会? 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()检查文件是否真的关闭,如果没有,则可能需要直接关闭其父进程。

【讨论】:

    【解决方案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.
      }
    

    【讨论】:

    • 我的文件正被另一个进程使用,所以我需要关闭那个进程(线程)才能删除文件。
    【解决方案3】:

    在您的代码中,您不对 IsFileInUse 结果做任何事情。

    这个File.Create(file ).Close(); 也不会关闭另一个进程打开的文件。您需要关闭打开文件的进程,如果是您自己的应用程序,请先关闭文件句柄,然后再尝试删除文件。

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

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多