C# 在所有子目录中查找具有特定扩展名的文件数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27570/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 08:16:38  来源:igfitidea点击:

Find number of files with a specific extension, in all subdirectories

提问by Espo

Is there a way to find the number of files of a specific type without having to loop through all results inn a Directory.GetFiles() or similar method? I am looking for something like this:

有没有办法找到特定类型的文件数量,而不必遍历 Directory.GetFiles() 或类似方法中的所有结果?我正在寻找这样的东西:

int ComponentCount = MagicFindFileCount(@"c:\windows\system32", "*.dll");

I know that I can make a recursive function to call Directory.GetFiles , but it would be much cleaner if I could do this without all the iterating.

我知道我可以创建一个递归函数来调用 Directory.GetFiles ,但是如果我可以在没有所有迭代的情况下做到这一点,它会更清晰。

EDIT:If it is not possible to do this without recursing and iterating yourself, what would be the best way to do it?

编辑:如果不递归和迭代自己就不可能做到这一点,那么最好的方法是什么?

采纳答案by Jon Limjap

You should use the Directory.GetFiles(path, searchPattern, SearchOption)overload of Directory.GetFiles().

您应该使用Directory.GetFiles()Directory.GetFiles(path, searchPattern, SearchOption)重载。

Path specifies the path, searchPattern specifies your wildcards (e.g., *, *.format) and SearchOption provides the option to include subdirectories.

Path 指定路径,searchPattern 指定通配符(例如,*、*.format),SearchOption 提供包含子目录的选项。

The Length property of the return array of this search will provide the proper file count for your particular search pattern and option:

此搜索的返回数组的 Length 属性将为您的特定搜索模式和选项提供正确的文件计数:

string[] files = directory.GetFiles(@"c:\windows\system32", "*.dll", SearchOption.AllDirectories);

return files.Length;

EDIT:Alternatively you can use Directory.EnumerateFiles method

编辑:或者你可以使用Directory.EnumerateFiles 方法

return Directory.EnumerateFiles(@"c:\windows\system32", "*.dll", SearchOption.AllDirectories).Count();

回答by Lasse V. Karlsen

Someone has to do the iterating part.

必须有人来做迭代部分。

AFAIK, there is no such method present in .NET already, so I guess that someone has to be you.

AFAIK,.NET 中已经没有这样的方法了,所以我想有人必须是你。

回答by jfs

You can use this overload of GetFiles:

您可以使用 GetFiles 的此重载:

Directory.GetFiles Method (String, String, SearchOption)

Directory.GetFiles 方法(字符串、字符串、搜索选项

and this member of 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.

AllDirectories- 在搜索操作中包括当前目录和所有子目录。此选项包括重新分析点,如搜索中的已安装驱动器和符号链接。

GetFiles returns an array of string so you can just get the Length which is the number of files found.

GetFiles 返回一个字符串数组,因此您可以获取 Length,即找到的文件数。

回答by Huppie

Using recursion your MagicFindFileCount would look like this:

使用递归,您的 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;
  }

Though Jon's solutionmight be the better one.

尽管乔恩的解决方案可能是更好的解决方案

回答by Sauleil

I was looking for a more optimized version. Since I haven't found it, I decided to code it and share it here:

我正在寻找更优化的版本。由于我还没有找到它,我决定对其进行编码并在这里分享:

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

All the solutions using the GetFiles/GetDirectories are kind of slow since all those objects need to be created. Using the enumeration, it doesn't create any temporary objects (FileInfo/DirectoryInfo).

所有使用 GetFiles/GetDirectories 的解决方案都有些慢,因为所有这些对象都需要创建。使用枚举,它不会创建任何临时对象 (FileInfo/DirectoryInfo)。

see Remarks http://msdn.microsoft.com/en-us/library/dd383571.aspxfor more information

有关详细信息,请参阅备注http://msdn.microsoft.com/en-us/library/dd383571.aspx

回答by Dean

The slickest method woud be to use linq:

最巧妙的方法是使用 linq:

var fileCount = (from file in Directory.EnumerateFiles(@"H:\iPod_Control\Music", "*.mp3", SearchOption.AllDirectories)
                    select file).Count();

回答by DraxReaper

I have an app which generates counts of the directories and files in a parent directory. Some of the directories contain thousands of sub directories with thousands of files in each. To do this whilst maintaining a responsive ui I do the following ( sending the path to ADirectoryPathWasSelectedmethod):

我有一个应用程序,它在父目录中生成目录和文件的计数。一些目录包含数千个子目录,每个子目录中有数千个文件。为了在保持响应式用户界面的同时做到这一点,我执行以下操作(将路径发送到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);
        }
    }
}