C#:使用Directory.GetFiles获取具有固定长度的文件

时间:2009-06-08 02:47:00

标签: c# .net windows filenames long-filenames

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

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

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

alt text

4 个答案:

答案 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.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'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);

更换琴弦有点贵。您可以添加所需的扩展名。