8

Directory.GetFiles(LocalFilePath, searchPattern);

MSDN 注释:

在 searchPattern 中使用星号通配符时,例如“.txt”,当扩展名正好是三个字符时的匹配行为与扩展名长度大于或小于三个字符时不同。文件扩展名正好是三个字符的 searchPattern 返回具有三个或更多字符扩展名的文件, 其中前三个字符与 searchPattern 中指定的文件扩展名匹配。文件扩展名为一个、两个或三个以上字符的 searchPattern 仅返回扩展名与 searchPattern 中指定的文件扩展名完全匹配的文件。当使用问号通配符时,该方法只返回与指定文件扩展名匹配的文件。例如,给定目录中的两个文件,“file1.txt”和“file1.txtother”,搜索模式为“file? 。文本”只返回第一个文件,而搜索模式“文件.txt" 返回两个文件。

以下列表显示了 searchPattern 参数的不同长度的行为:

  • *.abc返回具有.abc, .abcd, .abcde, .abcdef, 等扩展名的文件。

  • *.abcd仅返回扩展名为.abcd.

  • *.abcde仅返回扩展名为.abcde.

  • *.abcdef仅返回扩展名为.abcdef.

searchPattern参数设置为*.abc,如何返回扩展名为.abc、 not.abcd等的文件.abcde

也许这个功能会起作用:

    private bool StriktMatch(string fileExtension, string searchPattern)
    {
        bool isStriktMatch = false;

        string extension = searchPattern.Substring(searchPattern.LastIndexOf('.'));

        if (String.IsNullOrEmpty(extension))
        {
            isStriktMatch = true;
        }
        else if (extension.IndexOfAny(new char[] { '*', '?' }) != -1)
        {
            isStriktMatch = true;
        }
        else if (String.Compare(fileExtension, extension, true) == 0)
        {
            isStriktMatch = true;
        }
        else
        {
            isStriktMatch = false;
        }

        return isStriktMatch;
    }

测试程序:

class Program
{
    static void Main(string[] args)
    {
        string[] fileNames = Directory.GetFiles("C:\\document", "*.abc");

        ArrayList al = new ArrayList();

        for (int i = 0; i < fileNames.Length; i++)
        {
            FileInfo file = new FileInfo(fileNames[i]);
            if (StriktMatch(file.Extension, "*.abc"))
            {
                al.Add(fileNames[i]);
            }
        }

        fileNames = (String[])al.ToArray(typeof(String));

        foreach (string s in fileNames)
        {
            Console.WriteLine(s);
        }

        Console.Read();
    }

还有其他更好的解决方案吗?

4

5 回答 5

10

答案是您必须进行后过滤。单独的 GetFiles无法做到这一点。这是一个将发布处理您的结果的示例。有了这个,您可以将搜索模式与 GetFiles 一起使用,也可以不使用 - 无论哪种方式都可以。

List<string> fileNames = new List<string>();
// populate all filenames here with a Directory.GetFiles or whatever

string srcDir = "from"; // set this
string destDir = "to"; // set this too

// this filters the names in the list to just those that end with ".doc"
foreach (var f in fileNames.All(f => f.ToLower().EndsWith(".doc")))
{
    try
    {
        File.Copy(Path.Combine(srcDir, f), Path.Combine(destDir, f));
    }
    catch { ... }
}
于 2009-01-13T04:08:08.010 回答
5

不是错误,反常但有据可查的行为。*.doc 基于 8.3 后备查找匹配 *.docx。

您将不得不手动对结果进行后过滤,以便以 doc 结尾。

于 2009-01-13T04:05:00.327 回答
0

因为对于“*.abc”,GetFiles 将返回 3 个或更多的扩展名,任何在“.”之后长度为 3 的内容都会返回。是完全匹配的,任何更长的都不是。

string[] fileList = Directory.GetFiles(path, "*.abc");

foreach (string file in fileList)
{
   FileInfo fInfo = new FileInfo(file);

   if (fInfo.Extension.Length == 4) // "." is counted in the length
   {
      // exact extension match - process the file...
   }
}

不确定上述性能 - 虽然它使用简单的长度比较而不是字符串操作,但每次循环都会调用 new FileInfo() 。

于 2009-01-13T11:12:02.383 回答
0

这在短期内无济于事,但在 MS Connect 帖子上对此问题进行投票可能会在未来改变事情。

http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=95415

于 2009-01-13T10:08:11.590 回答
0

使用 linq....

    string strSomePath = "c:\\SomeFolder";
string strSomePattern = "*.abc";
string[] filez = Directory.GetFiles(strSomePath, strSomePattern);

var filtrd = from f in filez
         where f.EndsWith( strSomePattern )
         select f;

foreach (string strSomeFileName in filtrd)
{
    Console.WriteLine( strSomeFileName );
}
于 2009-01-13T07:06:07.340 回答