当搜索模式包含3个扩展字符时,.NET的Directory.GetFiles()中的奇怪功能

时间:2012-01-10 08:49:46

标签: .net getfiles system.io.directory

我最近碰到了微软的一个奇怪的功能:

假设我们的文件夹c:\tmp123包含3个文件 -
1.txt
2.txtx
3.txtxt

a)在3个退回的物品中调用Directory.GetFiles(@"C:\tmp123", "*.txt")收益率 b)在1个退回的项目中调用Directory.GetFiles(@"C:\tmp123", "*.txtx")收益。

根据Microsoft的说法,这是预期的行为(参见MSDN中的注释)。

我的问题是:

  1. 为什么微软决定拥有如此奇怪的功能?

  2. 我如何克服这个问题?
    即如何让搜索模式仅返回*.txt个扩展名而不返回*.txtx*.txtstarngefunctionality等?

4 个答案:

答案 0 :(得分:2)

这样做的原因是向后兼容。

Windows最初是作为MSDOS顶部的图形界面构建的,只有名称为8个字符的文件,扩展名最多为3个。 MSDOS文件系统的扩展允许Windows具有更长的文件名和扩展名,但这些文件名仍会在MSDOS中显示为8.3文件名。

由于Windows上的命令提示符是MSDOS中旧命令解释程序的演变,这意味着保留了一些“不合时宜的”行为(如3个字母的搜索模式),以便在“过去的日子”或“旧时代”中构建应用程序和脚本老定时器“不会破坏。

(另一个例子是大多数Windows文件系统都不区分大小写,是的,你猜对了,因为MSDOS没有套管)

答案 1 :(得分:1)

如果您想要一种解决方法,您只需检索所有文件路径

即可
var files = Directory.GetFiles(@"C:\tmp123");

然后根据需要按扩展名过滤

var txtFiles = files.Where(f => f.EndsWith(".txt"));
var txtxFiles = files.Where(f => f.EndsWith(".txtx"));

答案 2 :(得分:0)

我愿意下注这与后向兼容性有关。我没有看到提到的这个问题,但是this Raymond Chen blogpost提到了这方面的一些奇怪之处:<​​/ p>

  

[...] FCB匹配算法的一些怪癖持续存在于Win32中,因为   他们已经成了成语。

     

例如,如果您的模式以.*结尾,那么   .*被忽略。如果没有此规则,模式*.*将仅匹配   包含点的文件,可能会破坏所有的90%   这个星球上的批处理文件,以及每个人的肌肉记忆,因为   运行Windows NT 3.1的每个人都在*.*意味着的世界中长大   所有文件。

     

作为另一个例子,以点结尾的模式实际上并不存在   匹配以点结尾的文件;它匹配没有扩展名的文件。   如果问号立刻出现,问号可以匹配零个字符   在点之前。

答案 3 :(得分:0)

以下是另一种解决方法,可帮助过滤掉带有扩展名的文件,例如“.txtxt”:

var Files = System.IO.Directory.GetFiles("*.txt").Where(item => item.Extension.ToString().ToLower() == ".txt");