检查文件是否存在异步?

Joh*_*son 10 c# file-exists async-await

我希望有一个 File.ExistsAsync()

我有:

bool exists = await Task.Run(() => File.Exists(fileName));
Run Code Online (Sandbox Code Playgroud)

使用线程就像反模式一样.有更干净的方式吗?

小智 5

好久没发这个帖子了,今天才发现……

ExistsAsync绝对应该是一件事。事实上,在 UWP 中,您必须使用异步方法来查找文件是否存在,因为它可能需要超过 50 毫秒的时间(任何“可能”花费超过 50 毫秒的内容在 UWP 语言中都应该是异步的)。

然而,事实并非如此UWP。我需要它的原因是检查folder.exists网络共享、远程磁盘或空闲磁盘上是否会阻止 UI。aysnc因此,我可以将所有消息(如“检查...”)放入其中,但如果没有(或ViewModel、或timers等),UI 就不会更新。

你的代码:

bool exists = await Task.Run(() => File.Exists(fileName));
Run Code Online (Sandbox Code Playgroud)

工作完美。在我的代码中,我同时拥有 (ExistsExistsAsync),这样我就可以Exists()在非 UI 线程上运行时运行,而不必担心开销。


Ric*_*son -14

没有 File.ExistsAsync 可能是有充分理由的;因为拥有一个完全没有意义;File.Exists 不会花费很长时间;我测试文件存在时为0.006255ms,文件不存在时为0.010925ms。

有时调用 File.Exists 是明智的;然而,通常我认为正确的解决方案是打开文件(从而防止删除),捕获任何异常 - 因为不能保证文件在调用 File.Exists 后将继续存在。

当您想创建一个新文件而不覆盖旧文件时:

File.Open("fn", FileMode.CreateNew)
Run Code Online (Sandbox Code Playgroud)

对于大多数用例,我认为 File.Open() (无论是现有的还是创建新的)会更好,因为一旦调用成功,您将拥有文件的句柄并能够用它执行某些操作。即使使用文件的存在作为标志,我想我仍然会打开和关闭它。我唯一一次真正使用 File.Exists 是在调用浏览器之前检查本地 HTML 文件是否存在,以便在不存在时显示一条不错的错误消息。

不能保证 File.Exists 之后其他东西不会删除该文件;因此,如果您在检查 File.Exists 后确实打开了它,则 open 调用仍然可能会失败。

在我的测试中,在网络驱动器上使用 FileExists 需要比 File.Open 更长的时间,File.Exists 需要 1.5967 毫秒,而 File.OpenRead 需要 0.3927 毫秒)

也许如果你能详细说明你这样做的原因,我们就能更好地回答;在那之前我会说你不应该这样做

  • 如果文件位于网络驱动器上怎么办?那么,即使是像查找文件是否存在这样简单的事情也可能需要很长时间。 (76认同)
  • 好奇如果文件位于当前处于停止状态的辅助硬盘上,File.Exists 可能需要多长时间,因此需要 5-10 秒才能启动。AFAIK,Windows 默认情况下会停止辅助驱动器 20 分钟左右的不活动状态,我想在电池电量充足的笔记本上,即使在主驱动器上也会发生这种情况。 (7认同)
  • 我必须不同意这个问题(是的,我知道,两年后,但它出现在我正在寻找的东西中>.<)。您不应该使用异常处理来处理正常的逻辑流(即,文件不存在并不例外,除非您刚刚检查过它确实存在)。这几乎总是一个糟糕的设计。唯一一次不是这样的情况是没有其他方法可以做某事,即便如此,这通常也归咎于设计不佳的 API。 (3认同)
  • @RichardHarrison 我同意 Tyler W 的观点。您应该使用 File.Exists 来尝试避免创建异常,当然您不能依赖结果,但异常应该就是这样 - 异常。异常应该是控制代码中逻辑流的次要机制,而不是主要机制。您是否考虑了在计时中抛出和捕获异常所需的时间? (2认同)