file.exists 是判断文件是否存在的首选方法,它轻量、语义清晰、不抛异常;但仅检测普通文件的物理存在,不处理权限、网络延迟或长路径限制等问题。

用 File.Exists 最直接判断文件是否存在
绝大多数场景下,File.Exists 就是你要用的函数。它接受一个字符串路径,返回 true 或 false,不抛异常,语义清晰。
注意点:
-
File.Exists只检查路径是否指向一个**实际存在的普通文件**,对目录、符号链接、不存在的驱动器均返回false - 路径必须是**完整路径**或相对于当前工作目录的有效路径;相对路径容易在服务端或不同启动方式下失效
- 如果路径含非法字符(如
、<code>|),会直接抛ArgumentException,不是返回false
示例:
bool exists = File.Exists(@"C: empconfig.json"); // true 或 false
为什么不用 try/catch 包裹 FileStream 开启判断?
有人习惯用“打开失败即不存在”的思路,比如:
try { using (var fs = new FileStream(path, FileMode.Open)) { ... } } catch (FileNotFoundException) { ... }这不可取,原因很实在:
- 异常开销大,
File.Exists是轻量系统调用,而FileStream构造涉及权限校验、句柄分配等 - 捕获
FileNotFoundException不能覆盖所有“不存在”情况——比如路径存在但无读权限,会抛UnauthorizedAccessException - 你本意是查“是否存在”,却提前占用了文件句柄,还可能触发防病毒软件扫描
需要同时判断“存在且可读”怎么办?
File.Exists 不管权限,只管物理存在。若业务强依赖可读性(比如配置加载),得额外检查:
- 先用
File.Exists快速筛掉根本不存在的路径 - 再用
File.GetAccessControl+AuthorizationRuleCollection查 ACL(较重,仅必要时用) - 更实用的做法:直接尝试
File.ReadAllText或FileStream,捕获UnauthorizedAccessException和IOException,把“存在但不可读”当作独立错误分支处理
示例(推荐):
if (!File.Exists(path)) throw new FileNotFoundException($"File not found: {path}");
try { var content = File.ReadAllText(path); } catch (UnauthorizedAccessException) { /* handle permission issue */ }网络路径、UNC 路径和长路径要注意什么?
File.Exists 支持 UNC 路径(如 \servershareile.txt),但有隐性限制:
- 如果目标共享不可达(服务器关机、网络中断),调用会阻塞数秒后才返回
false,不是立刻失败 - Windows 默认禁用长路径(>260 字符),若路径超长且未启用系统级支持,
File.Exists直接返回false(即使文件真实存在) - .NET 5+ 在项目文件中加
<enablelongpaths>true</enablelongpaths>并确保 Windows 组策略已开启,才能可靠处理长路径
真正难缠的是“路径存在但暂时不可达”的中间态——它既不是明确存在,也不是明确不存在,File.Exists 的布尔返回掩盖了这个现实。










