我试图使用Directory.GetFiles()方法检索多种类型的文件列表,如mp3的和jpg的。以下两种方法我都试过了,但都没有成功:
Directory.GetFiles("C:\\path", "*.mp3|*.jpg", SearchOption.AllDirectories);
Directory.GetFiles("C:\\path", "*.mp3;*.jpg", SearchOption.AllDirectories);
有没有办法一次就能搞定?
我试图使用Directory.GetFiles()方法检索多种类型的文件列表,如mp3的和jpg的。以下两种方法我都试过了,但都没有成功:
Directory.GetFiles("C:\\path", "*.mp3|*.jpg", SearchOption.AllDirectories);
Directory.GetFiles("C:\\path", "*.mp3;*.jpg", SearchOption.AllDirectories);
有没有办法一次就能搞定?
当前回答
我不能使用. where方法,因为我在. net Framework 2.0中编程(Linq只在. net Framework 3.5+中被支持)。
下面的代码不区分大小写(因此.cab或.cab也会被列出)。
string[] ext = new string[2] { "*.CAB", "*.MSU" };
foreach (string found in ext)
{
string[] extracted = Directory.GetFiles("C:\\test", found, System.IO.SearchOption.AllDirectories);
foreach (string file in extracted)
{
Console.WriteLine(file);
}
}
其他回答
下面是一种获得过滤文件的简单而优雅的方法
var allowedFileExtensions = ".csv,.txt";
var files = Directory.EnumerateFiles(@"C:\MyFolder", "*.*", SearchOption.TopDirectoryOnly)
.Where(s => allowedFileExtensions.IndexOf(Path.GetExtension(s)) > -1).ToArray();
我想知道为什么有这么多“解决方案”张贴?
如果我对GetFiles如何工作的新手理解是正确的,那么只有两个选项,上面的任何解决方案都可以归结为:
GetFiles,然后是filter:速度很快,但在应用过滤器之前,由于存储开销,是内存杀手 在GetFiles时过滤:设置的过滤器越多,速度越慢,但由于没有存储开销,内存使用量就越低。这在上面的一篇文章中有一个令人印象深刻的基准测试:每个过滤器选项都会导致一个单独的GetFile-operation,因此硬盘的同一部分会被读取几次。
在我看来,选项1)是更好的,但使用SearchOption。像C:\这样的文件夹中的所有目录会占用大量内存。 因此,我将创建一个递归子方法,使用选项1遍历所有子文件夹)
这应该导致每个文件夹上只有1个getfiles -操作,因此速度很快(选项1),但只使用少量内存,因为在每个子文件夹读取后应用过滤器->开销在每个子文件夹后删除。
如果我说错了,请指正。就像我说的,我对编程很陌生,但我想对事情有更深入的了解,最终在这方面做得很好:)
下面的函数搜索多个以逗号分隔的模式。你也可以指定一个排除,例如:"!web。Config”将搜索所有文件并排除“web.config”。模式可以混合使用。
private string[] FindFiles(string directory, string filters, SearchOption searchOption)
{
if (!Directory.Exists(directory)) return new string[] { };
var include = (from filter in filters.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries) where !string.IsNullOrEmpty(filter.Trim()) select filter.Trim());
var exclude = (from filter in include where filter.Contains(@"!") select filter);
include = include.Except(exclude);
if (include.Count() == 0) include = new string[] { "*" };
var rxfilters = from filter in exclude select string.Format("^{0}$", filter.Replace("!", "").Replace(".", @"\.").Replace("*", ".*").Replace("?", "."));
Regex regex = new Regex(string.Join("|", rxfilters.ToArray()));
List<Thread> workers = new List<Thread>();
List<string> files = new List<string>();
foreach (string filter in include)
{
Thread worker = new Thread(
new ThreadStart(
delegate
{
string[] allfiles = Directory.GetFiles(directory, filter, searchOption);
if (exclude.Count() > 0)
{
lock (files)
files.AddRange(allfiles.Where(p => !regex.Match(p).Success));
}
else
{
lock (files)
files.AddRange(allfiles);
}
}
));
workers.Add(worker);
worker.Start();
}
foreach (Thread worker in workers)
{
worker.Join();
}
return files.ToArray();
}
用法:
foreach (string file in FindFiles(@"D:\628.2.11", @"!*.config, !*.js", SearchOption.AllDirectories))
{
Console.WriteLine(file);
}
在。net 2.0中(没有Linq):
public static List<string> GetFilez(string path, System.IO.SearchOption opt, params string[] patterns)
{
List<string> filez = new List<string>();
foreach (string pattern in patterns)
{
filez.AddRange(
System.IO.Directory.GetFiles(path, pattern, opt)
);
}
// filez.Sort(); // Optional
return filez; // Optional: .ToArray()
}
然后使用它:
foreach (string fn in GetFilez(path
, System.IO.SearchOption.AllDirectories
, "*.xml", "*.xml.rels", "*.rels"))
{}
或者你可以直接将扩展名字符串转换为string ^
vector <string> extensions = { "*.mp4", "*.avi", "*.flv" };
for (int i = 0; i < extensions.size(); ++i)
{
String^ ext = gcnew String(extensions[i].c_str());;
String^ path = "C:\\Users\\Eric\\Videos";
array<String^>^files = Directory::GetFiles(path,ext);
Console::WriteLine(ext);
cout << " " << (files->Length) << endl;
}