目录'C:\ temp'有两个名为'GZ96A7005.tif'和'GZ96A7005001.tif'的文件。它们具有不同的长度和相同的扩展名。现在我运行下面的代码:
string[] resultFileNames = Directory.GetFiles(@"C:\temp", "????????????.tif");
'resultFileNames'返回两个项'c:\ temp \ GZ96A7005.tif'和'c:\ temp \ GZ96A7005001.tif'。 但是Window Search可以正常工作。这就是为什么以及如何得到我想要的?
答案 0 :(得分:7)
对于Directory.GetFiles,?表示“完全为零或一个字符。”另一方面,您可以使用DirectoryInfo.GetFiles,为此?表示“完全是一个角色”(显然你想要的)。
编辑:
完整代码:
string[] resultFileNames = (from fileInfo in new DirectoryInfo(@"C:\temp").GetFiles("????????????.tif") select fileInfo.Name).ToArray();
您可以跳过ToArray,只需将resultFileNames设为IEnumerable<string>
。
人们报告这在MS .NET上对他们不起作用。以下精确代码适用于Ubuntu Hardy上的Mono。我同意有两个相关的类使用不同的约定并不真正有意义。但是,这就是文档(上面链接)所说的,Mono符合文档。如果微软的实现没有,他们就有一个错误:
using System;
using System.IO;
using System.Linq;
public class GetFiles
{
public static void Main()
{
string[] resultFileNames = (from fileInfo in new DirectoryInfo(@".").GetFiles("????????????.tif") select fileInfo.Name).ToArray();
foreach(string fileName in resultFileNames)
{
Console.WriteLine(fileName);
}
}
}
答案 1 :(得分:5)
我知道我以前曾在某处读过这篇文章,但我现在能找到的最好的就是Raymond Chen's blog post中对它的引用。关键是Windows为每个具有长文件名的文件保留一个短(8.3)文件名,以实现向后兼容性,文件名通配符与长文件名和短文件名匹配。您可以通过打开命令提示符并运行“dir /x
”来查看这些短文件名。通常,获取与????????.tif
(8)匹配的文件列表将返回其文件名中包含8个或更少字符的文件列表以及.tif扩展名。但每个文件名长的文件也都有一个包含8.3个字符的短文件名,因此它们都匹配此过滤器。
在您的情况下,GZ96A7005.tif
和GZ96A7005001.tif
都是长文件名,因此它们都有一个8.3短文件名,匹配????????.tif
(任何包含8个或更多?
的文件名)。
更新...来自MSDN:
因为此方法检查 具有8.3文件名的文件名 格式和长文件名格式, 搜索模式类似于“
*1*.txt
” 可能会返回意外的文件名。对于 例如,使用搜索模式 “*1*.txt
”返回“longfilename.txt
” 因为等效的8.3文件名 格式为“LONGFI~1.TXT
”。
更新:MSDN文档为Directory.GetFiles()和DirectoryInfo.GetFiles()中的“?
”通配符指定了不同的行为。但是,文档似乎是错误的。请参阅Matthew Flaschen's answer。
答案 2 :(得分:1)
?字符匹配“零个或一个”字符...所以从你拥有的我想象你的搜索模式将匹配任何以“.tif”结尾的文件,该文件的长度在0到12个字符之间。
尝试删除另一个文件,该文件只有三个字符长,带有“.tif”扩展名,并查看代码是否也选择了该文件。我怀疑它会;)
就Windows搜索而言,最明确的是它没有使用相同的算法。的?字符可能与Directory.GetFiles(string,string)方法的.Net搜索模式规范中的含义有很大不同。
答案 3 :(得分:0)
string path = "C:/";
var files = Directory.GetFiles(path)
.Where(f => f.Replace(path, "").Length == 8);
更换琴弦有点贵。您可以添加所需的扩展名。