单次操作用 File,高频操作用 FileInfo;File.Exists 每次全量校验,FileInfo.Exists 仅构造时校验一次;FileInfo 不缓存 Length/时间戳等元数据,仍实时系统调用。

直接用 File 还是先 new 一个 FileInfo,取决于你对同一个文件的操作频次——单次操作选 File,反复读写/查属性选 FileInfo。这不是风格偏好,而是 .NET 底层安全检查和路径解析开销的真实差异。
File.Exists() 和 FileInfo.Exists 属性为什么性能不同
File.Exists(string path) 每次调用都会重新解析路径、检查访问权限、验证父目录是否存在,整个过程走完整 IO 路径校验;而 FileInfo.Exists 是实例属性,只在构造 FileInfo 对象时做一次路径合法性与安全检查,后续访问只是读内存字段。
- 高频轮询文件是否存在(比如监控日志生成):用
FileInfo实例 + 循环读.Exists,避免重复 IO 开销 - 一次性判断后就不再碰这个文件:直接
File.Exists(path)更轻量,省去 new 对象的堆分配 - 注意:
FileInfo构造时如果路径非法(如含非法字符、长度超限),会立即抛ArgumentException;File.Exists遇到同样问题则返回false
复制/移动/删除等操作该用 File.Copy 还是 FileInfo.CopyTo
语义上几乎等价,但调用方式和异常时机不同。例如 File.Copy(src, dst, true) 和 new FileInfo(src).CopyTo(dst, true) 最终都调用相同内核逻辑,区别在于:
-
File.Copy在执行时才校验src是否存在、dst父目录是否可写 —— 异常发生在方法调用时刻 -
FileInfo实例化时已确认src路径有效(否则构造失败),.CopyTo只校验目标位置 —— 异常更晚发生,但构造阶段已过滤掉明显错误 - 如果要对同一源文件连续执行
CopyTo、MoveTo、.Length,必须用FileInfo;否则每次都要传路径,重复解析 + 安全检查
获取文件大小、创建时间等元数据时别踩 FileInfo.Length 的坑
FileInfo.Length 是属性,但它的值不是缓存在对象里的——每次访问都会触发一次 GetFileAttributesEx 系统调用(Windows)或 stat(Unix-like)。如果你在循环里反复读 .Length,实际做了多次系统调用。
- 需要多次读取元数据(比如比对大小+时间戳+权限):建议一次性读完所有属性,或自己缓存
.Length值 -
File.GetLastWriteTime(path)同样每次调用都走系统 API;而FileInfo.LastWriteTime也是实时查询,不是“构造时快照” - 真正只查一次就缓存的,是
FileInfo构造时的路径合法性、是否存在、是否为文件等基础判定
什么时候必须用 FileInfo 而不能用 File
当你要操作的目标不是“某个路径”,而是“那个文件实体本身”时,FileInfo 不可替代:
- 需要原子性地修改多个属性:比如同时设置
.IsReadOnly = true和.Attributes |= FileAttributes.Hidden - 要复用同一个文件句柄上下文(虽然不常见,但
FileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.Read)比File.Open多一层封装控制) - 配合
FileSystemWatcher响应事件时,事件参数给的是FileSystemEventArgs.FullPath,此时 new 一个FileInfo是最自然的后续操作入口 - 路径来自用户输入且需长期持有(如配置管理器类中保存一个
FileInfo字段),避免每次操作都拼接字符串或重复校验
真正容易被忽略的是:FileInfo 的“缓存优势”仅限于路径解析和初始安全性检查,它不缓存文件内容、不缓存时间戳、不缓存长度——这些仍是实时系统调用。别因为用了 FileInfo 就默认它“更快”,关键看你怎么用。


















