今天遇到一个神奇的Directory问题,和大家介绍下。

毅仔同学也研究了这个问题 更加详细,大家可以关注.NET/Windows:删除文件夹后立即判断,有可能依然存在 - walterlv


问题描述

简单描述下问题,

当你调用System.IO.Directory.Delete删除一个文件夹,

然后立即用System.IO.Directory.Exists进行判断会概率性返回true。

也就是说System.IO.Directory.Exists在检测一个刚刚被删除的文件夹时可能得到错误结果

代码如下

using System;
using System.IO;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            var path = @"F:\test\huangtengxiao";

            while (true)
            {
                Directory.Delete(path);
                if (Directory.Exists(path))
                {
                    throw new InvalidOperationException("系统出bug了");
                }
                Directory.CreateDirectory(path);
            }
        }

      
    }
}

运行大约3-5s就会触发exception

image-20200515180131302

源码分析

去referencesouce里面看看源码。

发现Directory.Exists最终是调用FindFirstFile这个windowsAPI,判断这个文件的标记(注意对于操作系统来说,文件和文件夹都是属于file)。

而Directory.Delete,最终是调用RemoveDirectory。

image-20200515183356058

image-20200515185111805

猜想

因此对这个问题的猜想是,系统调用RemoveDirectory之后,只是暂时标记移除了文件夹。

而在随后的一个时机才会真正执行移除。

所以在很短的时间内,还可以通过FindFirstFile获取文件的Attribute。

因此可以Directory.Exists返回true


参考文档:


本文会经常更新,请阅读原文: https://xinyuehtx.github.io/post/%E4%B8%8D%E8%A6%81%E5%9C%A8Directory%E5%88%A0%E9%99%A4%E5%90%8E%E7%AB%8B%E5%88%BB%E8%B0%83%E7%94%A8Directory.Exist.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

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