有没有办法找到特定类型的文件数,而无需在Directory.GetFiles()或类似方法中循环遍历所有结果?我正在寻找这样的东西:
int ComponentCount = MagicFindFileCount(@"c:\windows\system32", "*.dll");
我知道我可以创建一个递归函数来调用Directory.GetFiles,但是如果我可以在没有所有迭代的情况下执行此操作会更加清晰。
编辑:如果在没有递归和迭代的情况下无法做到这一点,那么最好的方法是什么?
答案 0 :(得分:35)
您应该使用Directory.GetFiles()的Directory.GetFiles(path, searchPattern, SearchOption)重载。
Path指定路径,searchPattern指定通配符(例如,*,*。format),SearchOption提供包含子目录的选项。
此搜索的返回数组的Length属性将为您的特定搜索模式和选项提供正确的文件计数:
string[] files = directory.GetFiles(@"c:\windows\system32", "*.dll", SearchOption.AllDirectories);
return files.Length;
编辑:您也可以使用Directory.EnumerateFiles method
return Directory.EnumerateFiles(@"c:\windows\system32", "*.dll", SearchOption.AllDirectories).Count();
答案 1 :(得分:8)
最简单的方法是使用linq:
var fileCount = (from file in Directory.EnumerateFiles(@"H:\iPod_Control\Music", "*.mp3", SearchOption.AllDirectories)
select file).Count();
答案 2 :(得分:7)
您可以使用GetFiles的重载:
和SearchOption的这个成员:
AllDirectories - 包含当前内容 目录和所有子目录 在搜索操作中。这个选项 包括像装载的重新分析点 驱动器和符号链接 搜索范围。
GetFiles返回一个字符串数组,这样你就可以得到长度,即找到的文件数。
答案 3 :(得分:6)
我一直在寻找更优化的版本。由于我还没有找到它,我决定编写代码并在此处分享:
public static int GetFileCount(string path, string searchPattern, SearchOption searchOption)
{
var fileCount = 0;
var fileIter = Directory.EnumerateFiles(path, searchPattern, searchOption);
foreach (var file in fileIter)
fileCount++;
return fileCount;
}
使用GetFiles / GetDirectories的所有解决方案都很慢,因为需要创建所有这些对象。使用枚举,它不会创建任何临时对象(FileInfo / DirectoryInfo)。
请参阅备注http://msdn.microsoft.com/en-us/library/dd383571.aspx了解更多信息
答案 4 :(得分:1)
使用递归,您的MagicFindFileCount将如下所示:
private int MagicFindFileCount( string strDirectory, string strFilter ) {
int nFiles = Directory.GetFiles( strDirectory, strFilter ).Length;
foreach( String dir in Directory.GetDirectories( strDirectory ) ) {
nFiles += GetNumberOfFiles(dir, strFilter);
}
return nFiles;
}
虽然Jon's solution可能更好。
答案 5 :(得分:1)
我有一个应用程序,可以生成父目录中的目录和文件的计数。一些目录包含数千个子目录,每个目录中包含数千个文件。要在保持响应式ui的同时执行此操作,请执行以下操作(将路径发送到 ADirectoryPathWasSelected 方法):
public class DirectoryFileCounter
{
int mDirectoriesToRead = 0;
// Pass this method the parent directory path
public void ADirectoryPathWasSelected(string path)
{
// create a task to do this in the background for responsive ui
// state is the path
Task.Factory.StartNew((state) =>
{
try
{
// Get the first layer of sub directories
this.AddCountFilesAndFolders(state.ToString())
}
catch // Add Handlers for exceptions
{}
}, path));
}
// This method is called recursively
private void AddCountFilesAndFolders(string path)
{
try
{
// Only doing the top directory to prevent an exception from stopping the entire recursion
var directories = Directory.EnumerateDirectories(path, "*.*", SearchOption.TopDirectoryOnly);
// calling class is tracking the count of directories
this.mDirectoriesToRead += directories.Count();
// get the child directories
// this uses an extension method to the IEnumerable<V> interface,
// which will run a function on an object. In this case 'd' is the
// collection of directories
directories.ActionOnEnumerable(d => AddCountFilesAndFolders(d));
}
catch // Add Handlers for exceptions
{
}
try
{
// count the files in the directory
this.mFilesToRead += Directory.EnumerateFiles(path).Count();
}
catch// Add Handlers for exceptions
{ }
}
}
// Extension class
public static class Extensions
{
// this runs the supplied method on each object in the supplied enumerable
public static void ActionOnEnumerable<V>(this IEnumerable<V> nodes,Action<V> doit)
{
foreach (var node in nodes)
{
doit(node);
}
}
}
答案 6 :(得分:0)
有人必须做迭代部分。
AFAIK,.NET中已经没有这样的方法,所以我想有人必须是你。