4

I have a List of string that contains files in which should be ignored for manipulating purposes. So I'm curious of how to handle the situation that has a wild card in it.

For example, the possible inputs in my List of String are:

C:\Windows\System32\bootres.dll
C:\Windows\System32\*.dll

The first example I think is easy to handle, I can just do a string equals check (ignoring case) to see if a file matches. However I am not sure how to determine if the given file may match the wild card expression in the list.

A little background into what I am doing. A user is allowed to copy a file to/from a location, however, if the file matches any file in my List of String I don't want to allow the copy.

There might be a must better approach to handling this.

The files I want to exclude are read in from a configuration file, and I receive the string value of the path that is attempting to be copied. Seems like I have all of the information I need to complete the task, it's just a matter of what is the best approach.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Tada
  • 1,585
  • 2
  • 16
  • 26

2 Answers2

2
IEnumerable<string> userFiles = Directory.EnumerateFiles(path, userFilter);

// a combination of any files from any source, e.g.:
IEnumerable<string> yourFiles = Directory.EnumerateFiles(path, yourFilter);
// or new string[] { path1, path2, etc. };

IEnumerable<string> result = userFiles.Except(yourFiles);

To parse a semicolon-delimited string:

string input = @"c:\path1\*.dll;d:\path2\file.ext";

var result = input.Split(";")
                  //.Select(path => path.Trim())
                  .Select(path => new
                  {
                      Path = Path.GetFullPath(path), //  c:\path1
                      Filter = Path.GetFileName(path) // *.dll
                  })
                  .SelectMany(x => Directory.EnumerateFiles(x.Path, x.Filter));
abatishchev
  • 98,240
  • 88
  • 296
  • 433
  • This would prevent writing a new file, say "C:\Windows\System32\somedllyoudonthave.dll" would it? – hometoast Jun 06 '12 at 18:39
  • @hometoast: Sorry, don't follow you, elaborate please. – abatishchev Jun 06 '12 at 18:43
  • It's the same as Tada's comment in Stefan's answer. This would prevent copying source files that match a filter, but not if you're trying to exclude targets. – hometoast Jun 06 '12 at 18:48
  • Without rambling, this only prevents filtering the source, not the target in a File.Copy. For instance filter C:\*.dll, It seems in your example I can File.Copy("D:\mydir\my.dll","C:\") – hometoast Jun 06 '12 at 18:54
  • @hometoast: Maybe I misread OP's question, but I see it as 2 filters: including (by user), excluding (by system), and resulting (which the question is about). – abatishchev Jun 07 '12 at 07:15
1

You could use Directory.GetFiles() and use the file name of the path to see if there is any matching file:

string[] filters = ...
return filters.Any(f => 
    Directory.GetFiles(Path.GetDirectoryName(f), Path.GetFileName(f)).Length > 0);

Update:
I indeed got it totally wrong. You have a set of file filters containing wildcard characters and want to check the user input against these. You could use the solution provided by @hometoast in the comments:

// Configured filter:
string[] fileFilters = new [] 
{ 
  @"C:\Windows\System32\bootres.dll", 
  @":\Windows\System32\*.dll" 
}

// Construct corresponding regular expression. Note Regex.Escape!
RegexOptions options = RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase;

Regex[] patterns = fileFilters
  .Select(f => new Regex("^" + Regex.Escape(f).Replace("\\*", ".*") + "$", options))
  .ToArray(); 

// Match against user input:
string userInput = @"c:\foo\bar\boo.far";
if (patterns.Any(p => p.IsMatch(userInput)))
{ 
  // user input matches one of configured filters
}
Community
  • 1
  • 1
Stefan
  • 14,530
  • 4
  • 55
  • 62
  • 2
    What if the file doesn't currently exist? I think this approach would work if I could always assume the excluded files were present. – Tada Jun 06 '12 at 17:31
  • @Tada, I think it's about coping files. I assumed OP wanted to filter on source files... Otherwise you are right... – Stefan Jun 06 '12 at 17:37