我最近碰到了微软的一个奇怪的功能:
假设我们的文件夹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中的注释)。
我的问题是:
为什么微软决定拥有如此奇怪的功能?
我如何克服这个问题?
即如何让搜索模式仅返回*.txt
个扩展名而不返回*.txtx
,*.txtstarngefunctionality
等?
答案 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");