过滤文件名:获取*.abc而不*.abcd,或*.abcde等

发布于 2024-07-11 21:00:42 字数 2433 浏览 8 评论 0原文

Directory.GetFiles(LocalFilePath, searchPattern);

MSDN 注释:

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

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

  • *.abc 返回扩展名为 .abc.abcd、.abcde.abcdef 等。

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

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

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

searchPattern 参数设置为 *.abc 时,如何返回扩展名为 .abc 而不是 .abcd< 的文件/code>、.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();
    }

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

Directory.GetFiles(LocalFilePath, searchPattern);

MSDN Notes:

When using the asterisk wildcard character in a searchPattern, such as ".txt", the matching behavior when the extension is exactly three characters long is different than when the extension is more or less than three characters long. A searchPattern with a file extension of exactly three characters returns files having an extension of three or more characters, where the first three characters match the file extension specified in the searchPattern. A searchPattern with a file extension of one, two, or more than three characters returns only files having extensions of exactly that length that match the file extension specified in the searchPattern. When using the question mark wildcard character, this method returns only files that match the specified file extension. For example, given two files, "file1.txt" and "file1.txtother", in a directory, a search pattern of "file?.txt" returns just the first file, while a search pattern of "file.txt" returns both files.

The following list shows the behavior of different lengths for the searchPattern parameter:

  • *.abc returns files having an extension of .abc, .abcd, .abcde, .abcdef, and so on.

  • *.abcd returns only files having an extension of .abcd.

  • *.abcde returns only files having an extension of .abcde.

  • *.abcdef returns only files having an extension of .abcdef.

With the searchPattern parameter set to *.abc, how can I return files having an extension of .abc, not .abcd, .abcde and so on?

Maybe this function will work:

    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;
    }

Test Program:

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();
    }

Anybody else better solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

闻呓 2024-07-18 21:00:42

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

The answer is that you must do post filtering. GetFiles alone cannot do it. Here's an example that will post process your results. With this you can use a search pattern with GetFiles or not - it will work either way.

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 { ... }
}
烦人精 2024-07-18 21:00:42

不是错误,而是有悖常理但有据可查的行为。 *.doc 根据 8.3 后备查找匹配 *.docx。

您必须手动对以 doc 结尾的结果进行后过滤。

Not a bug, perverse but well-documented behavior. *.doc matches *.docx based on 8.3 fallback lookup.

You will have to manually post-filter the results for ending in doc.

神经大条 2024-07-18 21:00:42

使用 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 );
}

use 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 );
}
嘿看小鸭子会跑 2024-07-18 21:00:42

这在短期内不会有帮助,但在 MS Connect 帖子上针对此问题进行投票可能会在未来改变情况。

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

This won't help in the short term, but voting on the MS Connect post for this issue may get things changed in the future.

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

人间☆小暴躁 2024-07-18 21:00:42

因为对于“*.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() 。

Since for "*.abc" GetFiles will return extensions of 3 or more, anything with a length of 3 after the "." is an exact match, and anything longer is not.

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...
   }
}

Not sure of the performance of the above - while it uses simple length comparisons rather than string manipulations, new FileInfo() is called each time around the loop.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文