首页 > 其他分享 >dotnet 已知问题 使用 Directory

dotnet 已知问题 使用 Directory

时间:2023-09-05 15:02:06浏览次数:47  
标签:已知 路径 Directory 枚举 文件夹 dotnet bug

在 dotnet 里面,可以使用 Directory.EnumerateXXX 系列方法进行枚举文件或文件夹。在准备枚举驱动器根路径的文件或文件夹时,可能获取到错误的路径。错误的步骤在于传入的是如 C: 不带斜杠的路径,且存在同驱动器磁盘下的非根路径工作路径

特别感谢 神樹桜乃若凡 两位大佬,让我明白了此问题和原因

此问题已报告给 dotnet 官方,详细请看 https://github.com/dotnet/runtime/issues/82085

这是一个稍微复杂的问题,大部分情况下大家不会遇到。这是一个从 .NET Core 3.1 到 .NET 7 都存在的问题,且基本上和系统环境无关

在 dotnet 里面可以使用 Directory.EnumerateXXX 系列方法进行枚举文件或文件夹,比如 Directory.EnumerateFiles 和 Directory.EnumerateFileSystemEntries 等方法。在使用这些方法进行枚举驱动器的根路径,如 C: 盘的文件或文件夹时,如果传入的路径参数是不带斜杠的,如 C: 而不是 C:\ 时,如果同时此时的工作路径是同驱动器下的非根路径,如 C:\lindexi 文件夹时,将会枚举出错误的路径

以下是 神樹桜乃 大佬给出的最简复现步骤

先在 C 盘创建一个名为 bug 的文件夹,在此文件夹里面放入 a b c 三个文件

接着设置工作路径为 C:\bug 且运行以下代码

foreach (var item in Directory.EnumerateFiles("C:"))
{
    Console.WriteLine(item);
}

此时的输出居然是如下代码

C:\a
C:\b
C:\c

也就是中间的 bug 文件夹没有输出,输出的是错误的路径。预期的输出应该如下

C:\bug\a
C:\bug\b
C:\bug\c

这个已知问题的核心原因是在 dotnet 底层里面调用的 GetFullPathNameW 函数行为和 dotnet 预期的不相同,如 官方文档 描述如下内容

If you specify "U:" the path returned is the current directory on the "U:" drive

也就是如果传入参数是 C: 不带斜杠的,将会使用传入的驱动器的当前工作路径。这也就导致了工作路径是同驱动器下的非根路径将会枚举到工作路径下的文件或文件夹,也就是上面例子里可以枚举到 a 和 b 和 c 文件的原因。只不过在 dotnet 的对外输出层拼接路径时,依然用的是传入的 C: 进行拼接,从而导致了输出错误

有一个可以用来实验的步骤是:先在 C 盘创建 lindexi 文件夹,打开 cmd 进入 C:\lindexi 文件夹,再使用 dotnet run 命令运行测试的项目,在测试的项目里面运行 Console.WriteLine(Path.GetFullPath("C:")); 这句代码。可以看到输出的是 C:\lindexi 文件夹,证明了 Windows 的底层行为符合文档

如何规避此问题?只需要破坏其条件即可,也就是在传入路径参数加上斜杠后缀,如 C:\ 路径,即可解决此问题

标签:已知,路径,Directory,枚举,文件夹,dotnet,bug
From: https://www.cnblogs.com/lindexi/p/17679577.html

相关文章

  • dotnet 理解 IConfigurationProvider 的 GetChildKeys 方法用途
    我最近遇到了一个有趣的Bug让我调试了半天,这个Bug的现象是我的好多个模块都因为读取不到配置信息而炸掉,开始我没有定位到具体的问题,以为是我的配置服务器挂掉了。经过了半天的调试,才找到了是我新加入的使用COIN配置库的ReadonlyCoinConfiguration类型导致的,此ReadonlyCoi......
  • dotnet 警惕 ConcurrentDictionary 使用 FirstOrDefault 获取到非预期的首项
    在dotnet里面的ConcurrentDictionary是一个支持并发读写的线程安全字典,在这个字典里面有一些行为会出现随机性,即多次执行相同的代码返回的结果可能不相同。本文记录在ConcurrentDictionary使用FirstOrDefault获取到非预期的首项的问题在dotnet里面,无论是对List列表,还......
  • dotnet 警惕判断文件是否存在因为检查网络资源造成超长等待
    在使用System.IO.File.Exists方法时,绝大部分的情况下都是一个非常快捷且没有成本的,但是如果判断的文件是否存在,是从非自己完全控制的逻辑下进入的,那就需要警惕是否判断的文件路径属于一个网络资源。判断一个网络资源是否存在,是一个耗时不可确定行为,很有可能造成主线程卡顿如果......
  • dotnet 记 TaskCompletionSource 的 SetException 可能将异常记录到 UnobservedTaskEx
    本文将记录dotnet的一个已知问题,且是设计如此的问题。假定有一个TaskCompletionSource对象,此对象的Task没有被任何地方引用等待。在TaskCompletionSource被调用SetException或TrySetException方法时,将会记录一个存在异常且未捕获的Task对象。此Task对象将会在被G......
  • dotnet 读 WPF 源代码笔记 渲染层是如何将字符 GlyphRun 画出来的
    从业务代码构建出来GlyphRun对象,在WPF的渲染层里,如何利用GlyphRun提供的数据将字符在界面呈现出来。本文将和大家聊聊从WPF的渲染层获取到GlyphRun数据,到调用DirectX的各个渲染相关方法的过程,也就是WPF绘制文本字符的原理或者实现方法大家印象中的绘制一段文本是调......
  • dotnet 读 WPF 源代码笔记 聊聊 HwndWrapper
    我在阅读WPF源代码,在HwndWrapper的静态构造函数看到了申请了HwndWrapper.GetGCMemMessage这个Windows消息,好奇这个消息是什么功能的。通过阅读WPF源代码和写测试应用,了解到这是一个完全用来内部测试或调试的消息,没有任何业务上的功能在WPF的HwndWrapper的静态构造......
  • dotnet 读 WPF 源代码笔记 GlyphRun 的 DeviceFontName 的功能是什么
    在WPF里面的GlyphRun里,有一个令人迷惑的DeviceFontName属性,似乎给这个属性传入什么值,结果都不会有变更。通过阅读源代码,可以了解到,这是一个没什么用途的属性。本文将告诉大家这个属性的细节逻辑在上一篇博客WPF简单聊聊如何使用DrawGlyphRun绘制文本里面就提到如何创......
  • 已知16进制和透明度,使用JS语法求他们在一起的rgba。可以参考下面代码:
    事件起因:最近做的一个大转盘游戏页面样式编辑,背景透明度调整的时候,会导致字体一起变动,于是需要将背景演示的16进制和透明度一起转换成rgba。 functionhexToRgba(hex,alpha){//去掉可能包含的"#"符号if(hex.startsWith("#")){hex=hex.slice(1);}//解析1......
  • homebrew安装软件出现git问题fatal: not in a git directory,Error: Command failed w
    homebrew安装软件出现git问题问题fatal:notinagitdirectoryError:Commandfailedwithexit128:git问题查找1.brew-v查看问题logsuyf@suyfdeMac-mini~%brew-vHomebrew4.0.18-18-g64259a4fatal:detecteddubiousownershipinrepositoryat'/op......
  • Dotnet6 NPOI操作Excel基本操作总结
    背景需要对Excel进行读取和写入,目前使用Dotnet6开发环境,故直接使用。达到的效果:兼容.xls和.xlsx,识别行为空自动跳过,识别显示值,识别格式内容步骤Dotnet6Nuget安装NPOI,具体版本2.6.1,tips:搜索资料时,可能NPOI1与NPOI2可能有出入。使用方法获取相应文档对象......