c# -如何以优化的方式快速列出子目录中的文件
本文关键字:子目录 文件 方式快 优化 | 更新日期: 2023-09-27 18:10:13
我试图用以下方法列出根目录的所有子目录中的文件。但是当文件的数量达到数百万时,需要花费很多时间。有没有更好的方法来做这件事呢?
我使用的是。net 3.5,所以不能使用enumerator:-(
) ******************* Main *************
DirectoryInfo dir = new DirectoryInfo(path);
DirectoryInfo[] subDir = dir.GetDirectories();
foreach (DirectoryInfo di in subDir) //call for each sub directory
{
PopulateList(di.FullName, false);
}
*******************************************
static void PopulateList(string directory, bool IsRoot)
{
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + "dir /s/b '"" + directory + "'"");
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
string fileName = directory.Substring(directory.LastIndexOf('''') + 1);
StreamWriter writer = new StreamWriter(fileName + ".lst");
while (proc.StandardOutput.EndOfStream != true)
{
writer.WriteLine(proc.StandardOutput.ReadLine());
writer.Flush();
}
writer.Close();
}
删除所有与process相关的东西并尝试Directory。GetDirectories()和Directory.GetFiles()方法:
public IEnumerable<string> GetAllFiles(string rootDirectory)
{
foreach(var directory in Directory.GetDirectories(
rootDirectory,
"*",
SearchOption.AllDirectories))
{
foreach(var file in Directory.GetFiles(directory))
{
yield return file;
}
}
}
来自MSDN, SearchOption。AllDirectories:
包含当前目录和搜索中的所有子目录操作。该选项包括重新解析点,如挂载的驱动器和搜索中的符号链接。
在每个目录的循环中使用DirectoryInfo.GetFiles
肯定会更快,而不是产生大量的新进程来读取它们的输出。
对于数以百万计的文件,您实际上会遇到文件系统限制(参见此并搜索"300,000"),因此请考虑到这一点。
至于优化,我认为你真的想要延迟迭代,所以你必须p/Invoke到FindFirstFile
/FindNextFile
。
查看已经可用的目录。getfile过载。
例如:
var paths = Directory.GetFiles(root, "*", SearchOption.AllDirectories);
是的,这将花费很多时间。但是我不认为你可以仅仅使用。net类来提高它的性能。
假设您的数百万个文件分布在多个子目录中,并且您使用的是。net 4.0,您可以查看并行扩展。
使用并行foreach循环来处理子目录列表,可以使事情更快。
新的并行扩展也比在底层尝试多线程更安全,更容易使用。
要注意的一件事是确保将并发进程的数量限制在合理的范围内。