19

I just stumbled upon an undocumented behavior of the GetFiles methods in System.IO.Directory.

Whenever the searchPattern parameter passed to the method contains a reserved Windows device name, such as "nul.*" or "aux.bmp", the method returns an array containing the name of a nonexisting file, like C:\Users\ft1\nul or D:\aux, etc.

I wonder if those device names have a special meaning it that context, like "." or "..", or if this is just a sort of bug. Anyway, that still seems pretty weird. For example, this code snippet in C#:

string[] fileNames = Directory.GetFiles(@"C:\D:\..\..\...\", "con.txt");
foreach (string fileName in fileNames) Console.WriteLine(fileName);

prints

C:\D:\..\..\...\con

Any clues?

Tilak
  • 30,108
  • 19
  • 83
  • 131
GOTO 0
  • 42,323
  • 22
  • 125
  • 158

3 Answers3

28

This is known. It is an operating system design regarding Naming Files, Paths, and Namespaces (Windows)

Excerpt:

Do not use the following reserved names for the name of a file: CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9. Also avoid these names followed immediately by an extension; for example, NUL.txt is not recommended. For more information, see Namespaces.

These are basically filename aliases (namespaces), so they always exist globally (in every folder). If you attempt to enumerate them, you'll get them back because they do exist.

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
  • 1
    Do you know if the .NET Framework has any built-in list of such reserved names? – GOTO 0 Dec 31 '12 at 17:49
  • 6
    That is a good question, it probably would be better to ask that as an actual SO question, but since the question [How check if given string is legal (allowed) file name under Windows?](http://stackoverflow.com/questions/62771/how-check-if-given-string-is-legal-allowed-file-name-under-windows) is already asked, I'll give you the link. – Erik Philips Dec 31 '12 at 17:53
  • This is exactly right - ahh, the price of dealing with legacy systems...a lot of this comes from the days of DOS. :) – JerKimball Dec 31 '12 at 19:15
  • @JerKimball it's not really legacy as much as it's just the price you have to pay to have a textual input/output interface. – Erik Philips Dec 31 '12 at 19:41
10

These are reserved words by MSDOS/NTFS.

From Wikipedia:

In addition, in Windows and DOS utilities, some words might also be reserved and can not be used as filenames. For example, DOS device files:

CON, PRN, AUX, CLOCK$, NUL
COM0, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9
LPT0, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9.

Systems that have these restrictions cause incompatibilities with some other filesystems. For example, Windows will fail to handle, or raise error reports for, these legal UNIX filenames: aux.c, q"uote"s.txt, or NUL.txt.

NTFS filenames that are used internally include:

$Mft, $MftMirr, $LogFile, $Volume, $AttrDef, $Bitmap, $Boot, $BadClus, $Secure,
$Upcase, $Extend, $Quota, $ObjId and $Reparse
svick
  • 236,525
  • 50
  • 385
  • 514
Tilak
  • 30,108
  • 19
  • 83
  • 131
  • Thanks, I knew of the reserved MSDOS names but those internal NTFS filenames are new to me. I'll have to give them a look as I think they may also cause problems in my application. – GOTO 0 Dec 31 '12 at 17:54
0

As an addendum to this, had a related issue when using a json config file in an MSTest dll. When I called it Test_Settings_Develop.json, Directory.GetFiles found it, but said it did not exist, so my tests failed to run, on attempting to load it.

Renamed it to TestSettings_Develop.json and it worked.

Tony Hopkinson
  • 20,172
  • 3
  • 31
  • 39