有没有一种方法可以查找特定类型的文件数而不必遍历Directory.GetFiles()或类似方法中的所有结果? 我正在寻找这样的东西:
1
| int ComponentCount = MagicFindFileCount(@"c:\windows\system32","*.dll"); |
我知道我可以创建一个递归函数来调用Directory.GetFiles,但是如果我无需进行所有迭代就可以做到这一点将更加简洁。
编辑:如果不进行递归和迭代就不可能做到这一点,那么什么是最好的方法呢?
您应该使用Directory.GetFiles()的Directory.GetFiles(path,searchPattern,SearchOption)重载。
路径指定路径,searchPattern指定通配符(例如*,*。format),SearchOption提供包含子目录的选项。
此搜索的返回数组的Length属性将为您的特定搜索模式和选项提供正确的文件数:
1 2 3
| string[] files = directory.GetFiles(@"c:\windows\system32","*.dll", SearchOption.AllDirectories);
return files.Length; |
编辑:或者,您可以使用Directory.EnumerateFiles方法
1
| return Directory.EnumerateFiles(@"c:\windows\system32","*.dll", SearchOption.AllDirectories).Count(); |
最巧妙的方法是使用linq:
1 2
| var fileCount = (from file in Directory.EnumerateFiles(@"H:\iPod_Control\Music","*.mp3", SearchOption.AllDirectories)
select file).Count(); |
您可以使用此GetFiles重载:
Directory.GetFiles Method (String,
String, SearchOption)
以及SearchOption的该成员:
AllDirectories - Includes the current
directory and all the subdirectories
in a search operation. This option
includes reparse points like mounted
drives and symbolic links in the
search.
GetFiles返回一个字符串数组,因此您只需获取Length(即找到的文件数)即可。
我正在寻找一个更优化的版本。由于尚未找到它,我决定对其进行编码并在此处共享:
1 2 3 4 5 6 7 8
| 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/zh-cn/library/dd383571.aspx
我有一个应用程序,可以生成父目录中目录和文件的计数。其中一些目录包含数千个子目录,每个子目录中都包含数千个文件。为此,在保持响应式ui的同时,请执行以下操作(将路径发送到ADirectoryPathWasSelected方法):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| 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);
}
}
} |
使用递归,您的MagicFindFileCount看起来像这样:
1 2 3 4 5 6 7 8 9
| 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;
} |
尽管乔恩的解决方案可能是更好的解决方案。
有人必须做重复的部分。
AFAIK,.NET中已经不存在这样的方法,所以我想有人必须是您。