0

Given a list of files like this:

file_1.txt
file_2.txt
file_3.txt
file_4.txt
file_5.txt
file_6.txt

How do I invoke Directory.EnumerateFiles() to get a range or a list of files? For example

Directory.EnumerateFiles(Directory.GetCurrentDirectory(), "file_*.txt", SearchOption.TopDirectoryOnly)

would return all the six files above, and so far so good. But what if I want to get a range (i.e. from file_3.txt to file_5.txt) or a list (i.e. file_1.txt, file_4.txt and file_6.txt)?

What I'm looking for is something like this (the code here below doesn't work... it is just to give you an idea):

Directory.EnumerateFiles(Directory.GetCurrentDirectory(), "file_{3-5}.txt", SearchOption.TopDirectoryOnly)

to get a range of files

file_3.txt
file_4.txt
file_5.txt

... and then

Directory.EnumerateFiles(Directory.GetCurrentDirectory(), "file_{1,4,6}.txt", SearchOption.TopDirectoryOnly)

to get an exact list of files

file_1.txt
file_4.txt
file_6.txt

Any help would be appreciated.

j3d
  • 9,492
  • 22
  • 88
  • 172

3 Answers3

1

Directory.EnumerateFiles seems to only work with simple wildcards. However, according to this question/answer (How to find files according RegEx in C#). You could use LINQ and a regex match to do the filtering instead?

Community
  • 1
  • 1
revlayle
  • 71
  • 5
1

Combine it with LINQ:

Directory.EnumerateFiles(Directory.GetCurrentDirectory(), "file_*.txt").Skip(2).Take(3);

Directory.EnumerateFiles(Directory.GetCurrentDirectory(), "file_*.txt").Where(...);
Haney
  • 32,775
  • 8
  • 59
  • 68
1

Building on DavidH's answer.

Use LINQ and System.Text.Regular expressions to get the file list:

IEnumerable<string> files1to3 =  Directory.EnumerateFiles(@"C:\", "File*.txt", SearchOption.TopDirectoryOnly).Where(f => Regex.IsMatch(f, "File[1-3].txt"));
IEnumerable<string> files4to6 = Directory.EnumerateFiles(@"C:\", "File*.txt", SearchOption.TopDirectoryOnly).Where(f => Regex.IsMatch(f, "File[4,5,6].txt"));

In response to @j3d:

IEnumerable<string> files150to200 = Directory.EnumerateFiles(@"C:\", "File*.txt", SearchOption.TopDirectoryOnly).Where(f => Convert.ToInt32(Regex.Match(f, @"\d+").Value) >= 150 && Convert.ToInt32(Regex.Match(f, @"\d+").Value) <= 200);

For lists of file numbers you could do something like this:

System.Collections.ArrayList searchArrayList = new System.Collections.ArrayList();
searchArrayList.Add(new int[] { 1, 125, 1554 });

foreach (int[] i in searchArrayList) {
    IEnumerable<string> findFiles = Directory.EnumerateFiles(@"c:\", "File*.txt", SearchOption.TopDirectoryOnly).Where(f => i.Contains(Convert.ToInt32(Regex.Match(f, @"\d+").Value)));
}

Resource

Community
  • 1
  • 1
jiverson
  • 1,206
  • 12
  • 25
  • 1
    No need to call ToList(), EnumerateFiles returns an IEnumerable that can be used with Where as is – Panagiotis Kanavos Jul 29 '13 at 18:30
  • Thanks! I have removed the ToList() call. – jiverson Jul 29 '13 at 18:35
  • Just a comment... File[1-3]\.txt just works for numbers less than 10... what if I need to match file names like File333.txt? In other words, I need to specify any kind of range (e.g. File[150-200]\.txt) – j3d Aug 05 '13 at 20:34
  • OK, ranges work fine... and what about lists? How do I filter file names like File1.txt, File125.txt, or File1554.txt? I've tried .Where(f =>Regex.IsMatch(f, @"(1|125|1554)")); ... but it doesn't work. – j3d Aug 05 '13 at 21:45
  • Thank you very very much for your support! Really appreciated :-) – j3d Aug 06 '13 at 20:10