0

目录“C:\temp”有两个文件,分别名为“GZ96A7005.tif”和“GZ96A7005001.tif”。它们具有不同的长度和相同的扩展。现在我运行以下代码:

string[] resultFileNames = Directory.GetFiles(@"C:\temp", "????????????.tif");

“resultFileNames”返回两个项目“c:\temp\GZ96A7005.tif”和“c:\temp\GZ96A7005001.tif”。但是 Window Search 可以正常工作。这就是为什么以及如何得到我想要的?

替代文字

4

4 回答 4

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);
        }
    }
}
于 2009-06-08T02:55:17.017 回答
5

我知道我以前在某个地方读过这个,但我现在能找到的最好的是在Raymond Chen 的博客文章中对它的引用。关键是 Windows 为每个具有长文件名的文件保留一个短 (8.3) 文件名,以实现向后兼容性,并且文件名通配符与长文件名和短文件名匹配。您可以通过打开命令提示符并运行“ dir /x”来查看这些短文件名。通常,获取匹配????????.tif(8) 的文件列表会返回文件名中包含 8 个或更少字符且扩展名为 .tif 的文件列表。但是每个文件名长的文件也有一个 8.3 个字符的短文件名,所以它们都匹配这个过滤器

在您的情况下,GZ96A7005.tifGZ96A7005001.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 的回答

于 2009-06-08T04:26:54.327 回答
1

这 ?字符匹配“零或一”字符......所以从你所拥有的我想你的搜索模式将匹配任何以“.tif”结尾且长度在零到十二个字符之间的文件。

尝试将另一个只有三个字符长且扩展名为“.tif”的文件放入其中,然后查看代码是否也能找到它。我有一个偷偷摸摸的怀疑它会;)

就 Windows 搜索而言,它肯定不会在后台使用相同的算法。这 ?字符可能具有与 Directory.GetFiles(string, string) 方法的 .Net 搜索模式规范中的含义截然不同的含义。

于 2009-06-08T02:53:49.313 回答
0
string path = "C:/";
var files = Directory.GetFiles(path)
    .Where(f => f.Replace(path, "").Length == 8);

字符串替换的成本有点高。你可以添加任何你需要的扩展。

于 2009-06-08T03:45:20.133 回答