如果你在代码中使用了 FileInfo.Exists 实例方法来判断一个文件是否存在,也许会发现此方法可能错误地判断来一个文件是否真的存在。这是一个坑。

本文将介绍坑的原因,并提供填坑的办法。


问题代码

我们使用两种不同的方式判断文件是否存在:

  • FileInfo.Exists 实例方法
  • File.Exists 静态方法
static async Task Main(string[] args)
{
var filePath = @"C:\Users\lvyi\Desktop\walterlv.log";
var fileInfo = new FileInfo(filePath);
while (true)
{
Console.WriteLine($"FileInfo.Exists = {fileInfo.Exists}");
Console.WriteLine($" File.Exists = {File.Exists(filePath)}");
Console.WriteLine("----");
await Task.Delay(1000);
}
}

现在运行这个程序,我们会发现,中途删除了 walterlv.log 文件之后,FileInfo.Exists 依然返回了 true,而 File.Exists 已经开始返回 false 了。

原因分析

实际翻阅代码可以发现,FileInfo.ExistsFile.Exists 方法最终都是使用相同的方法来完成文件存在与否的判断。

这是 FileInfo.Exists 的判断:

public override bool Exists
{
[SecuritySafeCritical] get
{
try
{
if (this._dataInitialised == -1)
this.Refresh();
if (this._dataInitialised != 0)
return false;
return (this._data.fileAttributes & 16) == 0;
}
catch
{
return false;
}
}
}

这是 File.Exists 的最终判断:

public static bool FileExists(string fullPath)
{
Interop.Kernel32.WIN32_FILE_ATTRIBUTE_DATA data = new Interop.Kernel32.WIN32_FILE_ATTRIBUTE_DATA();
int errorCode = FillAttributeInfo(fullPath, ref data, returnErrorOnNotFound: true); return (errorCode == 0) && (data.dwFileAttributes != -1)
&& ((data.dwFileAttributes & Interop.Kernel32.FileAttributes.FILE_ATTRIBUTE_DIRECTORY) == 0);
}

只不过,FileInfo.Exists 只会在没有初始化的时候初始化一次,而 File.Exists 是没有缓存的,每次都是直接去获取文件的属性(这就涉及到 IO)。

解决办法

所以,如果你正在处理的文件在不同的时间可能存在也可能不存在,那么最好使用 File.Exists 来判断文件存在与否,而不是使用 FileInfo.Exists 来判断。

不过,如果你需要一次性判断文件的非常多的信息(而不只是文件存在与否),那么依然建议使用 FileInfo,只不过在使用之前需要调用 Refresh 进行一次刷新。


我的博客会首发于 https://walterlv.com/,而 CSDN 和博客园仅从其中摘选发布,而且一旦发布了就不再更新。

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://blog.csdn.net/wpwalter),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

谨慎使用 FileInfo.Exists 实例方法,而是使用 File.Exists 静态方法替代的更多相关文章

  1. Linux启动网卡时出现RTNETLINK answers: File exists错误解决方法

    这里说一下,如果复制了虚拟机,设置新的MAC地址为什么? 在虚拟机的网络设置中--->高级.然后找到如下窗口,生成新的MAC地址即可. ----------------------------- ...

  2. RTNETLINK answers: File exists错误解决方法

    >一.写在前面: 因为是我刚学习linux好多问题需要解决,bolg仅作为记录自己的在技术这条道路上的点点滴滴. 二.事件起因: 最近因为女友的原因消沉的好长时间,在马哥那里的课程的结束到现在已 ...

  3. Git – fatal: Unable to create ‘/.git/index.lock’: File exists错误解决办法

    有时候在提交的时候,中间提交出错,导致有文件被lock,所以会报下面的错误: fatal: Unable to create ‘/msg/.git/index.lock’: File exists. ...

  4. linux下RTNETLINK answers: File exists的解决方案

    重启网卡时 出现 :RTNETLINK answers: File exists  提示 以下是网卡出来错误的解决方法: 第一种: 和 NetworkManager 服务有冲突,这个好解决,直接关闭 ...

  5. IIS目录下文件共享后System.IO.File.Exists返回false

    场景:在iis目录下,因为特殊需要共享一个文件夹,给到其他的技术人员访问,突然发现小小的操作,搞“大”了,使用 string path = Server.MapPath("~/file/te ...

  6. RTNETLINK answers: File exists错误

    解决ssh连接虚拟机出错,RTNETLINK answers: File exists 解决步骤如下: 使用ssh连接虚拟机的时候,发现目标主机无法连接,登录虚拟机,查看ssh监听是否开启: 发现监听 ...

  7. docker dead but pid file exists

    CentOS 6安装docker 报docker dead but pid file exists 执行 yum install epel-release yum install docker-io ...

  8. npm ERR! File exists: /XXX/xxx npm ERR! Move it away, and try again.

    今天抽空将我的静态服务 ks-server 之前留下的 bug(在node低版本情况下报错)维护了一下. 当我重新 npm link 时,如下错误: npm WARN ks-server@1.0.2 ...

  9. Centos7修改默认网卡名(改为eth0)以及网卡启动报错RTNETLINK answers: File exists处理

    安装好centos7版本的系统后,发现默认的网卡名字有点怪,为了便于管理,可以手动修改.下面对centos7版本下网卡重命名操作做一记录:1)编辑网卡信息[root@linux-node2~]# cd ...

随机推荐

  1. Android 使用SQLite

    SQLite简介 Google为Andriod的较大的数据处理提供了SQLite,他在数据存储.管理.维护等各方面都相当出色,功能也非常的强大.SQLite具备下列特点: 1.轻量级 使用 SQLit ...

  2. Tomcat 中文乱码 设置UTF-8编码 问题解决办法

    在Java Web开发中,http请求带有中文字符的URI如果不处理容易出现乱码问题:这是因为Tomcat容器默认编码是iso-8859-1引起的,因此要避免出现乱码就要需要做相应的处理.解决办法如下 ...

  3. 20170503xlVBA房地产数据分类连接

    Sub NextSeven_CodeFrame4() Application.ScreenUpdating = False Application.DisplayAlerts = False Appl ...

  4. java final修饰变量时的一种情况

    有如下一种场景. 1.在文件PaymentConfig.java中存在如下变量public static final desc="描述" 2.类Test.java中使用了desc变 ...

  5. Confluence 6 设置公共访问

    你可以通过为匿名用户启用 'Use Confluence' 权限来启用匿名用户的站点访问(也称为公共访问) 一个匿名用户的定义为一个不需要登录就可以访问 Confluence 站点.使用 Conflu ...

  6. 第二类斯特林数(转自http://www.cnblogs.com/gzy-cjoier/p/8426987.html )

    转自http://www.cnblogs.com/gzy-cjoier/p/8426987.html 侵删

  7. 『cs231n』作业3问题4选讲_图像梯度应用强化

    [注],本节(上节也是)的model是一个已经训练完成的CNN分类网络. 随机数图片向前传播后对目标类优化,反向优化图片本体 def create_class_visualization(target ...

  8. hdu1238 kmp

    You are given a number of case-sensitive strings of alphabetic characters, find the largest string X ...

  9. ASP.NET网页生命周期事件

    网页事件 典型的使用方式 PreInit PreInit事件是网页生命周期中非常早起的一个事件,在PreInit事件触发之后,就会加载用户设置信息与网页主题.我们通常使用PreInit事件来执行下列处 ...

  10. dp练习(9)——最大乘积

    1017 乘积最大 2000年NOIP全国联赛普及组NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Desc ...