Directory.GetFiles找到不存在的文件

19

我刚刚偶然发现了 System.IO.Directory 中的 GetFiles 方法的一个未记录行为。

每当传递给该方法的 searchPattern 参数包含一个保留的 Windows 设备名称,例如 "nul.*""aux.bmp" 时,该方法将返回一个包含不存在文件名的数组,如 C:\Users\ft1\nulD:\aux

我想知道这些设备名称在这个上下文中是否有特殊含义,就像“.”或“..”一样,还是这只是一种 bug。无论如何,这似乎仍然非常奇怪。 例如,以下 C# 代码片段:

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

打印

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

有线索吗?

3个回答

28

这是公知的。它是关于文件、路径和命名空间(Windows)的操作系统设计。

摘录:

不要使用以下保留名称作为文件名:CON,PRN,AUX,NUL,COM1,COM2,COM3,COM4,COM5,COM6,COM7,COM8,COM9,LPT1,LPT2,LPT3,LPT4,LPT5,LPT6,LPT7,LPT8 和 LPT9。同时避免在名称后立即添加扩展名;例如,不推荐使用NUL.txt。有关更多信息,请参见名称空间。

这些基本上是文件名别名(命名空间),因此它们在全局范围内始终存在(在每个文件夹中)。如果您尝试枚举它们,将得到它们,因为它们确实存在。


1
你知道.NET Framework 是否有任何内置的保留名称列表吗? - GOTO 0
6
这是一个很好的问题,最好将其作为实际的SO问题进行提问,但由于已经有了问题如何检查给定字符串是否是Windows下允许的合法文件名?,我会给你提供链接。 - Erik Philips
这完全正确 - 啊,处理遗留系统的代价...很多都来自DOS时代。 :) - JerKimball
@JerKimball 这并不是传统的遗留问题,而是为了拥有文本输入/输出接口所必须付出的代价。 - Erik Philips

10

这些是MSDOS/NTFS中的保留字

来自维基百科

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

谢谢,我知道保留的MSDOS名称,但是那些内部NTFS文件名对我来说是新的。我得看看它们,因为我认为它们也可能会在我的应用程序中引起问题。 - GOTO 0

0
作为补充,当我在一个MSTest dll中使用json配置文件时,遇到了相关问题。当我将其命名为Test_Settings_Develop.json时,Directory.GetFiles找到了它,但却说它不存在,因此我的测试无法运行,试图加载它时失败了。
将其重命名为TestSettings_Develop.json后,问题得到解决。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接