3

Using c# GetDirectories to retrieving folders immediately under the search directory. The code works for all other directories searched EXCEPT a single directory. Specifically, GetDirectories returns two different folders, one contains the search pattern while the other one doesn't contain the search pattern.

Wildcard search pattern is *43* in my example.

Tried pretty much everything I could think of.
Strangely, if I change the case of any one character of the "WINCE_TEST_IMAGE_41" folder name then the GetDirectories returns the expected (and correct) single directory that matches the search pattern which is "*43*" (again). For example, change the "C" to a "c"...then the single directory containing 43 is returned...

Setup:
I have .NET Framework SDK 4.8 installed (latest installation as of 9/3/2019).
1. Create folder "C:\Temp\WINCE_OS_IMAGES"
2. Create subfolders in folders named:
* "WINCE_TEST_IMAGE_40"
* "WINCE_TEST_IMAGE_41"
* "WINCE_TEST_IMAGE_42"
* "WINCE_TEST_IMAGE_43"
* "WINCE_TEST_IMAGE_44".

So that the directory structure is:

C:\Temp
      \WINCE_OS_IMAGES
            \WINCE_TEST_IMAGE40
            \WINCE_TEST_IMAGE41
            \WINCE_TEST_IMAGE42
            \WINCE_TEST_IMAGE43
            \WINCE_TEST_IMAGE44

Code:
v is a parameter input to the method so I have assigned a value to help reproduce the issue.

string v = "43";

string[] dirs2 = Directory.GetDirectories(@"C:\Temp\WINCE_OS_IMAGES", "*" + 
    v + "*", SearchOption.TopDirectoryOnly);

foreach (string str in dirs2)
{
    Console.WriteLine(str);
}

Expected: GetDirectories statement returns only the directory ending in "43".

Actual:
GetDirectories statement returns two directories, one ending in "41" and the other ending in "43".

jpop1
  • 31
  • 1
  • 2
  • Is it a typo? " *" + v + " *" There is a space before and after the * – Steve Sep 03 '19 at 18:25
  • Note, you can format code by indenting it by four spaces. In the editor, mark the code and press the `{}` button. – Olivier Jacot-Descombes Sep 03 '19 at 18:26
  • you need to isolate further, as "on my machine" your test returns just one directory like it should – Lanorkin Sep 03 '19 at 18:29
  • I cannot reproduce the issue. See also https://stackoverflow.com/editing-help – Olivier Jacot-Descombes Sep 03 '19 at 18:43
  • Thanks for giving it a try to reproduce. BTW, the initial entry didn't allow * (asterisks) to be used. The white space is now gone. Also, updated to indicate using .NET Framework 4.8. I'll need to check if the issue is occurring on the original machine with possibly an earlier version of .NET Framework. Tried it with .NET Framework 4.7.2 and it still occurs. – jpop1 Sep 03 '19 at 20:52
  • 1
    Maybe it's about the short (8.3) filenames. To find out, open a CMD window there and type `DIR /X` – H H Sep 03 '19 at 21:16
  • 1
    Thank you Henk, your comment seems spot on. I did what you suggested and the directories that are returned contain the string "43" in either the short (8.3) format or the long format. I haven't investigated eliminating the short format from the getdirectories search but this appears to be a bug(?). – jpop1 Sep 04 '19 at 03:50

2 Answers2

1

The documentation for GetFiles (didn't find this statement for GetDirectories) says:

Note
Because this method checks against file names with both the 8.3 file name format and the long file name format, a search pattern similar to "*1*.txt" may return unexpected file names. For example, using a search pattern of "*1*.txt" returns "longfilename.txt" because the equivalent 8.3 file name format is "LONGFI~1.TXT".

I assume that the same is true for GetDirectories.

Therefore, you will have to filter the result yourself (e.g. with regex or with string.Contains()).

var dirs2 = Directory.GetDirectories(@"C:\Temp\WINCE_OS_IMAGES", "*" + 
                                     v + "*", SearchOption.TopDirectoryOnly)
    .Where(d => d.Contains(v));

foreach (string str in dirs2)
{
    Console.WriteLine(str);
}

Note: you are searching for a number, therefore the character case is not an issue. If you need a case insensitive search, you cannot simply use Contains, since it has no overload allowing case insensitive search. You could use Colonel Panic's answer to the question Case insensitive 'Contains(string)' or compare with

v = v.ToLowerInvariant();
...
.Where(d => d.ToLowerInvariant().Contains(v));
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
0
string[] dirs2 = Directory.GetDirectories(@"C:\Temp\WINCE_OS_IMAGES", "*" +
            v + "*", SearchOption.TopDirectoryOnly);

Remove the white space.