@@ -52,71 +52,55 @@ in stringBuilder.GetPinnableReference(true),
5252 // NB: This method assumes backslashes have been normalized to forward slashes
5353 // NB: This method operates on the actual file system
5454 private bool FileExistsCaseInsensitive ( ReadOnlySpan < char > filePath , ref ValueStringBuilder stringBuilder )
55- {
56- Debug . Assert ( ! RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ) ;
57-
58- var pathString = filePath . ToString ( ) ;
59- if ( _underlyingFileSystem . File . Exists ( pathString ) )
60- return true ;
55+ {
56+ Debug . Assert ( ! RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ) ;
57+
58+ var pathString = filePath . ToString ( ) ;
59+ if ( _underlyingFileSystem . File . Exists ( pathString ) )
60+ return true ;
6161
62- var segments = pathString . Split ( '/' ) ;
63- var currentPath = segments [ 0 ] . Length == 0 ? "/" : segments [ 0 ] ;
62+ var directory = _underlyingFileSystem . Path . GetDirectoryName ( pathString ) ;
63+ var fileName = _underlyingFileSystem . Path . GetFileName ( pathString ) ;
6464
65- var lastSegmentIndex = segments . Length - 1 ;
66- while ( lastSegmentIndex > 0 && string . IsNullOrEmpty ( segments [ lastSegmentIndex ] ) )
67- lastSegmentIndex -- ;
65+ if ( string . IsNullOrEmpty ( directory ) || string . IsNullOrEmpty ( fileName ) )
66+ return false ;
6867
69- for ( var i = 1 ; i < segments . Length ; i ++ )
70- {
71- var segment = segments [ i ] ;
72- if ( string . IsNullOrEmpty ( segment ) )
73- continue ;
68+ if ( ! _underlyingFileSystem . Directory . Exists ( directory ) )
69+ {
70+ if ( ! FileExistsCaseInsensitive ( directory . AsSpan ( ) , ref stringBuilder ) )
71+ return false ;
7472
75- var isLastSegment = i == lastSegmentIndex ;
73+ directory = stringBuilder . AsSpan ( ) . ToString ( ) ;
74+ }
7675
77- // Guard: if currentPath doesn't exist as a directory, bail out cheaply
78- if ( ! _underlyingFileSystem . Directory . Exists ( currentPath ) )
79- return false ;
76+ var files = _underlyingFileSystem . Directory . GetFiles ( directory ) ;
77+ var directories = _underlyingFileSystem . Directory . GetDirectories ( directory ) ;
8078
81- if ( isLastSegment )
79+ foreach ( var file in files )
8280 {
83- // Single IO call instead of GetFiles + GetDirectories
84- var entries = _underlyingFileSystem . Directory . GetFileSystemEntries ( currentPath ) ;
85- foreach ( var entry in entries )
81+ var name = _underlyingFileSystem . Path . GetFileName ( file ) ;
82+ if ( name . Equals ( fileName , StringComparison . OrdinalIgnoreCase ) )
8683 {
87- var name = _underlyingFileSystem . Path . GetFileName ( entry ) ;
88- if ( name . Equals ( segment , StringComparison . OrdinalIgnoreCase ) )
89- {
90- stringBuilder . Length = 0 ;
91- stringBuilder . Append ( entry ) ;
92- return true ;
93- }
84+ stringBuilder . Length = 0 ;
85+ stringBuilder . Append ( file ) ;
86+ return true ;
9487 }
95- return false ;
9688 }
9789
98- // Intermediate segment: resolve case-insensitively
99- var subDirs = _underlyingFileSystem . Directory . GetDirectories ( currentPath ) ;
100- string ? resolved = null ;
101- foreach ( var dir in subDirs )
90+ foreach ( var dir in directories )
10291 {
10392 var name = _underlyingFileSystem . Path . GetFileName ( dir ) ;
104- if ( name . Equals ( segment , StringComparison . OrdinalIgnoreCase ) )
93+ if ( name . Equals ( fileName , StringComparison . OrdinalIgnoreCase ) )
10594 {
106- resolved = dir ;
107- break ;
95+ stringBuilder . Length = 0 ;
96+ stringBuilder . Append ( dir ) ;
97+ return true ;
10898 }
10999 }
110100
111- if ( resolved is null )
112- return false ;
113-
114- currentPath = resolved ;
101+ return false ;
115102 }
116103
117- return false ;
118- }
119-
120104 private bool IsPathFullyQualified_Exists ( ReadOnlySpan < char > path )
121105 {
122106 // This is really tricky, because under Windows "/" or "\" do NOT
0 commit comments