过滤文件名:获取* .abc而不使用* .abcd或* .abcde,依此类推

时间:2009-01-13 03:55:44

标签: c# wildcard

Directory.GetFiles(LocalFilePath,searchPattern);

MSDN备注:

  

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

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

  • *.abc会返回扩展名为.abc.abcd.abcde.abcdef等的文件。

    < / LI>
  • *.abcd仅返回扩展名为.abcd的文件。

  • *.abcde仅返回扩展名为.abcde的文件。

  • *.abcdef仅返回扩展名为.abcdef的文件。

如果searchPattern参数设置为*.abc,我该如何返回扩展名为.abc,而不是.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();
    }

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

5 个答案:

答案 0 :(得分:9)

答案是必须进行后置过滤。单独的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 { ... }
}

答案 1 :(得分:5)

不是一个错误,有悖常理但记录良好的行为。 * .doc基于8.3回退查找匹配* .docx。

您必须手动过滤结果以结束doc。

答案 2 :(得分: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 );
}

答案 3 :(得分:0)

这在短期内无济于事,但对此问题的MS Connect帖子投票可能会在未来发生变化。

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

答案 4 :(得分: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...
   }
}

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