Exact file extension match with GetFiles()?
Asked Answered
M

8

8

I'd like to retrieve a list of files whose extensions match a specified string exactly.

DirectoryInfo di = new DirectoryInfo(someValidPath);
List<FileInfo> myFiles = new List<FileInfo>();
foreach (FileInfo fi in di.GetFiles("*.txt"))
{
    myFiles.Add(fi);
}

I get the files with extension *.txt but I also get files with the extension *.txtx, so what I've coded amounts to getting the files whose extension starts with txt.

This isn't what I want. Do I need to grab all of the filenames and do a regular expression match to "\\.txt$" (I think), or test each filename string with .EndsWith(".txt"), etc., to accomplish this?

Thanks!

Mathura answered 6/4, 2011 at 21:17 Comment(4)
Yes, you do. Is it so hard, and why do you need regulare expressions?Scaffold
Watch out, every answer forgets that Windows file names are case insensitive. You can get .TXT as well. Casing rules for file names are a bit nasty, you might want to check the string length.Bradleybradly
@Hans: Good point. Does Fredrik's answer handle the case insensitivity issue?Mathura
Erm, it's better. As I said, nasty, the file system keeps its own casing rules. Fredrik's code works if it is just .txtBradleybradly
T
4

Somewhat of a workaround, but you can filter out exact matches with the Where extesion method:

foreach (FileInfo fi in di.GetFiles("*.txt")
    .Where(fi => string.Compare(".txt", fi.Extension, StringComparison.OrdinalIgnoreCase) == 0))
{
   myFiles.Add(fi);
}

Note that this will make a case insensitive matching of the extension.

Thunder answered 6/4, 2011 at 21:25 Comment(0)
G
3

Using the AddRange feature of lists instead of doing the foreach loop and calling Add for each item returned by the expression below (which I save into the variable list).

var list = di.GetFiles("*.txt").Where(f => f.Extension == ".txt");
myFiles.AddRange(list);

I'm presuming you were just showing us a snippet of your code and myFiles already had values in it, if not, you could do instead.

List<FileInfo> myFiles = di.GetFiles("*.txt").Where(f => f.Extension == ".txt").ToList();
Gathard answered 6/4, 2011 at 21:51 Comment(1)
Edited and gave a bit more of an example.Gathard
R
2

Regex might be overkill. Use the extension on FileInfo.

foreach (FileInfo fi in di.GetFiles("*.txt").Where(f => f.Extension == ".txt"))
{
     myFiles.Add(fi);
} 
Ruhnke answered 6/4, 2011 at 21:23 Comment(2)
instead of foreach loop, you can do myFiles.AddRange( the expression )Gathard
@Chuck Savage: is "the expression" the part in the foreach loop following in?Mathura
U
1

Try this:

DirectoryInfo di = new DirectoryInfo(someValidPath); 
List<FileInfo> myFiles =  
    (
        from file in di.GetFiles("*.txt")
        where file.Extension == ".txt"
        select file
    ).ToList();
Unreflective answered 6/4, 2011 at 21:22 Comment(0)
H
1
DirectoryInfo di = new DirectoryInfo(someValidPath);
List<FileInfo> myFiles = new List<FileInfo>();
foreach (FileInfo fi in di.GetFiles("*.txt"))
{
   if (fi.Extension == ".txt")
      myFiles.Add(fi);
}
Hemiplegia answered 6/4, 2011 at 21:26 Comment(0)
E
0

Couldn't you just add an if and check the last four characters of the filename?

Excurved answered 6/4, 2011 at 21:27 Comment(0)
V
0

If you are using C# 2.0 Isn't easier ?

string fileExtensionFilter = "*.txt";
            DirectoryInfo di = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
            List<FileInfo> myFiles = new List<FileInfo>();
            foreach (FileInfo fi in di.GetFiles(fileExtensionFilter))
            {
                if (fi.Extension == fileExtensionFilter.Substring(1)) myFiles.Add(fi);
            }
Vision answered 6/4, 2011 at 21:44 Comment(0)
J
0

I had a user-supplied pattern so many of the other answers didn't suit me. I ended up with this more general purpose solution:

public string[] GetFiles(string path, string pattern)
{
    bool lastWildIsHook = false;
    if(pattern.EndsWith("?"))
    {
        pattern = pattern.Substring(0, pattern.Length - 1);
        lastWildIsHook = true;
    }
    var lastWildIndex = Math.Max(pattern.LastIndexOf("*"), pattern.LastIndexOf("?"));
    var endsWith = pattern.Length > lastWildIndex ? pattern.Substring(lastWildIndex + 1) : pattern;
    if(!lastWildIsHook)
        return Directory.GetFiles(path, pattern).Where(p => p.EndsWith(endsWith)).ToArray();
    else
        return Directory.GetFiles(path, pattern).Where(p => p.EndsWith(endsWith) || p.Substring(0, p.Length - 1).EndsWith(endsWith)).ToArray();
}
Jacynth answered 21/11, 2013 at 19:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.