你可以使用多个过滤器调用Directory.GetFiles()吗?
问题的出现原因是在获取文件列表时,需要根据多个过滤条件进行筛选,但是在使用Directory.GetFiles()方法时,只能传入一个过滤条件。解决方法是使用LINQ的Where()方法来对获取的文件列表进行进一步筛选。
以下是解决方法的具体代码:
string supportedExtensions = "*.jpg,*.gif,*.png,*.bmp,*.jpe,*.jpeg,*.wmf,*.emf,*.xbm,*.ico,*.eps,*.tif,*.tiff,*.g01,*.g02,*.g03,*.g04,*.g05,*.g06,*.g07,*.g08"; foreach (string imageFile in Directory.GetFiles(_tempDirectory, "*.*", SearchOption.AllDirectories).Where(s => supportedExtensions.Contains(Path.GetExtension(s).ToLower()))) { //do work here }
另外,有用户提出了一些问题和改进建议。其中一位用户询问如何将获取到的文件路径缩减为文件名,可以使用System.IO.Path.GetFileName()方法来实现。另一位用户指出Path.GetExtension()方法返回的是'.ext'而不是'*.ext'。还有一位用户提醒需要引入System.Linq命名空间才能使用.Where()方法。还有用户建议使用一个可靠的分隔符,如'|'而不是逗号来分隔扩展名,以避免扩展名中包含逗号的情况。另外还有用户提到了一个潜在的缺陷,即在supportedExtensions中包含的扩展名长度不等于文件实际扩展名时,仍然会匹配。为了解决这个问题,可以在测试时包含分隔符字符。重要的是,分隔符字符必须放在supportedExtensions的最后一个条目之后。还有一个缺陷是所有的.Contains解决方案都会包括没有扩展名的文件。
以上代码和改进建议可以帮助解决在使用Directory.GetFiles()方法时需要传入多个过滤条件的问题,并提供了获取文件名和其他相关操作的方法。
问题的出现原因是希望能够在调用`Directory.GetFiles()`方法时使用多个过滤器,以便在一个方法调用中获取满足多个条件的文件列表。
解决方法是使用以下代码:
private static string[] GetFiles(string sourceFolder, string filters, System.IO.SearchOption searchOption) { return filters.Split('|').SelectMany(filter => System.IO.Directory.GetFiles(sourceFolder, filter, searchOption)).ToArray(); }
这段代码中,我们将`filters`参数按照竖线分隔符分割成多个过滤器,并使用`SelectMany()`方法将每个过滤器应用于`Directory.GetFiles()`方法,最后使用`ToArray()`方法将结果转换为字符串数组。
此解决方法的好处是避免了前面排名靠前的答案可能存在的内存问题。但是需要注意的是,这种方法在性能上可能会比接受的答案慢一些。可以通过SpeedTest来进行性能比较。
如果需要并行处理获取文件列表,可以使用`Parallel.ForEach`方法。但是需要注意的是,这样做可能会受到IO带宽的限制。
需要注意的是,最后一条评论中的链接失效了。
问题出现的原因是在使用Directory.GetFiles()方法时,希望能够使用多个过滤器来筛选文件。解决方法是使用Directory.EnumerateFiles()方法替代Directory.GetFiles()方法,并在返回的文件数组上进行进一步的筛选。
对于.NET 4.0及更高版本,可以使用以下代码:
var files = Directory.EnumerateFiles("C:\\path", "*.*", SearchOption.AllDirectories) .Where(s => s.EndsWith(".mp3") || s.EndsWith(".jpg"));
对于较早版本的.NET,可以使用以下代码:
var files = Directory.GetFiles("C:\\path", "*.*", SearchOption.AllDirectories) .Where(s => s.EndsWith(".mp3") || s.EndsWith(".jpg"));
需要注意的是,这将返回一个包含所有文件的字符串数组,然后再根据指定的扩展名进行筛选。如果"C:\Path"下有大量文件,则可能会导致内存/性能问题。
可以通过以下方式改进代码:
var files = myDirInfo.GetFiles().Where(o => new[]{"mp3", "jpg"}.Contains(o.Extension.ToLower())).ToArray();
另外,可以使用IgnoreCase的方式来比较扩展名:
s.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase)
如果有许多可能的扩展名,可以创建一个包含所有扩展名的HashSet,并使用Contains方法进行筛选:
var validExtensions = new HashSet{"mp3", "jpg"}; var files = myDirInfo.GetFiles().Where(f => validExtensions.Contains(Path.GetExtension(f).ToLower()));
需要注意的是,在某些情况下,可能需要使用GetFiles()而不是EnumerateFiles(),例如如果希望按特定顺序处理文件,则需要在开始处理之前获取整个文件集合来确定顺序。
总之,根据问题的要求,需要先获取所有文件,然后再筛选它们。可以根据实际需求选择不同的方法,并注意性能和内存方面的考虑。