【问题标题】:Absolute Path with Wild Card filtering带有通配符过滤的绝对路径
【发布时间】:2012-06-06 17:26:12
【问题描述】:

我有一个字符串列表,其中包含出于操作目的应忽略的文件。所以我很好奇如何处理有外卡的情况。

例如,我的字符串列表中可能的输入是:

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

我认为第一个例子很容易处理,我可以做一个字符串等于检查(忽略大小写)来查看文件是否匹配。但是我不确定如何确定给定文件是否可以匹配列表中的通配符表达式。

我正在做的事情的一点背景。允许用户将文件复制到/从某个位置复制,但是,如果该文件与我的字符串列表中的任何文件匹配,我不想允许复制。

可能有更好的方法来处理这个问题。

我要排除的文件是从配置文件中读入的,我收到了试图复制的路径的字符串值。似乎我拥有完成任务所需的所有信息,这只是最佳方法的问题。

【问题讨论】:

标签: c# .net wildcard


【解决方案1】:
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);

解析分号分隔的字符串:

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

【讨论】:

  • 这会阻止写入新文件,比如“C:\Windows\System32\somedllyoudonthave.dll”会不会?
  • @hometoast:对不起,不关注你,请详细说明。
  • 这与 Tada 在 Stefan 的回答中的评论相同。这将阻止复制与过滤器匹配的源文件,但如果您尝试排除目标,则不会。
  • 不乱说,这只会阻止过滤源文件,而不是 File.Copy 中的目标文件。例如过滤器 C:*.dll,在你的例子中我可以 File.Copy("D:\mydir\my.dll","C:\")
  • @hometoast:也许我误读了 OP 的问题,但我将其视为 2 个过滤器:包括(按用户)、排除(按系统)和结果(问题所在)。
【解决方案2】:

您可以使用Directory.GetFiles(),并使用路径的文件名来查看是否有任何匹配的文件:

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

更新:
我确实完全错了。您有一组包含通配符的文件过滤器,并希望根据这些过滤器检查用户输入。您可以使用@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
}

【讨论】:

  • 如果文件当前不存在怎么办?我认为如果我总是可以假设排除的文件存在,这种方法会起作用。
  • @Tada,我认为这是关于应对文件。我假设 OP 想要过滤源文件......否则你是对的......
猜你喜欢
  • 2017-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-13
  • 1970-01-01
相关资源
最近更新 更多