【问题标题】:Checking if a file is in use without try catch?检查文件是否正在使用而不尝试捕获?
【发布时间】:2013-03-12 13:24:27
【问题描述】:

有没有一种方法可以检查文件是否正在使用或未被其他进程打开,而不仅仅是尝试打开它并捕获异常?有没有服务方法可以测试这种东西?

【问题讨论】:

  • 好吧,你为什么想知道?无论如何要打开文件?然后您可以跳过检查并直接尝试,因为无论如何您都可以参加比赛。
  • @Јοеу 不是必需的,但主要是它的原因,但是一旦涉及到第 3 方工具,确定文件是否可以打开或不能调用第 3 方的 open 方法会很有帮助,无论如何,我希望有这样的方法,而不是将 catch 语句作为计划的艺术来实施。
  • 这不是重复的,这里的重点是try catch的尝试,而不是一般情况下是否可能。
  • 如果 Hal 的 C 答案(不是标记为答案之一)对应于您在 David 的链接中需要的内容,那么您在此处有一个 .NET P/Invoke IsFileInUse 等效项:social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/…

标签: c# .net file exception file-access


【解决方案1】:

即使有,它也不会对您有多大好处,因为您仍然必须捕获异常以处理在您的初始检查和您实际尝试打开/访问之间文件不可用的竞争条件它。

我想不出初步防御检查有什么令人信服的优势。它只会导致不必要的代码重复。

如果有这样的IsFileAccessible 函数,它可能会被实现为一个巨大的try/catch 块,它试图打开文件、捕获失败并返回结果。

【讨论】:

  • @CodyGray Thnx 来回答,但这不就像检查文件的访问控制一样吗?但我确实有这个选项来询问这些访问控制而不必遇到 catch 语句,它仍然可能发生,但它不会成为我计划的一部分。
  • 你是对的。但是,尽管您最终无法避免检查异常,但拥有一个无需打开文件即可检查异常的函数仍然会很有趣。一些有用的工具确实提供了这些信息,而且它们不是基于 try/catch 代码。
  • @SimonMourier 不用 try/catch 就很容易做到。只需致电CreateFile
  • @DavidHeffernan - 对,那你为什么不把它作为答案呢?
  • 是否捕获异常无关紧要。关键是,真正知道是否可以打开文件的唯一方法是尝试打开它。在发明异常之前(并且仍然在不支持它们的语言中),OpenFile 函数(或等效函数)仅返回一个指示成功或特定错误条件的错误代码:FileNotFoundFileInUseUnauthorizedAccess等@两个
【解决方案2】:

我可以测试一个文件是否可以在不尝试的情况下打开吗 打开它?

.net 框架,就像下面的 Windows API 一样,不提供这样的功能。如果您想知道一个文件是否可以打开,您应该尝试打开它并检查是否失败。

【讨论】:

    【解决方案3】:

    避免try catch(但意味着尝试打开)的有趣方法是LockFile()CreateFile()函数:

    处理 WINAPI CreateFile(...)

    如果函数成功,则返回值是指定文件、设备、命名管道或邮件槽的打开句柄。

    如果函数失败,返回值为 INVALID_HANDLE_VALUE。要获取更多错误信息,请致电GetLastError


    BOOL WINAPI LockFile(...)

    如果函数成功,返回值非零 (真)。

    如果函数失败,则返回值为零 (FALSE)。要得到 扩展错误信息,请致电GetLastError

    这会锁定指定文件以供调用进程独占访问,并在失败时将错误信息写入线程的 last-error,可以使用 GetLastError 函数检索。

    仍然可以想象,在 unlockFile 和 OpenFile 之间,另一个进程可以锁定文件,但可以通过将文件锁定到需要打开的那一刻来最小化这段时间。

    【讨论】:

    • 问问自己 hFile 来自哪里?
    • 你的权利!我以 CreateFile 结束,虽然它没有抛出异常并启用 readbale 返回值,但它仍然尝试打开文件
    • 这正是我和其他人一直在告诉你的。碰巧打开文件的 .net 机制发出异常信号失败。 Win32 机制通过返回值发出错误信号。从根本上说,最终结果是一样的。
    • @DavidHeffernan 你需要走很长的路才能理解它,谢谢。但是.net 不能去所有正在运行的进程来检查是否有任何正在锁定文件,并提供这样的文件功能吗?我错过了什么吗?
    • @TwoMore 也许操作系统可以做到这一点(尽管就像大卫说的那样,它没有),但正如我在回答中解释的那样,它不会起到有用的目的。像这样的代码:if (FileExists(file)) { OpenFile(file); } 从根本上损坏了,因为它无法处理在调用FileExists()OpenFile() 之间文件丢失的情况。因此,您不妨尝试打开文件并处理导致的任何错误(无论是来自异常还是来自返回码)。我的回答讨论了由于您应用于问题的标签而导致的例外情况。
    【解决方案4】:

    你可以在 .net 4.5 中实现这个家伙,但它包含很多开销 http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-10
      • 1970-01-01
      • 2023-03-29
      相关资源
      最近更新 更多