gpt4 book ai didi

c# - EnumerateFiles() 如何工作?

转载 作者:行者123 更新时间:2023-11-30 17:05:52 25 4
gpt4 key购买 nike

我正在编写一个程序,当给定日期、文件夹路径和文件扩展名时,该程序将查看文件夹并查找上次访问时间从月初到当前日期的所有文件,并且只有具有传递的文件扩展名的文件。

我要查找的文件始终位于文件夹树中的同一级别,因此我可以在程序中编写代码以查找文件的挖掘距离。

目前我的节目一天大约需要一分钟,所以今天(16 号)大约需要十六分半钟。

我想制作一个程序来查找文件夹路径中某个日期范围内的所有文件,并从文件中提取信息。我只是不想编写程序的代码,以防万一我的公司改变了他们存储文件的方式。

我设法编写代码,如果给定一个文件夹,该程序将显示该日期范围内所有文件的名称,但这需要 25 分钟。这是代码

TimeSpan BeginningTime = DateTime.Now.TimeOfDay;
DateTime BeginningDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
DateTime EndingDate = DateTime.Now;
string[] FoldersToLookAt = { @"e:\", @"e:\Kodak Images\", @"e:\images\", @"e:\AFSImageMerge\" };
foreach (string FolderPath in FoldersToLookAt)
{
for (DateTime Date = BeginningDate; Date <= EndingDate; Date = Date.AddDays(1))
{
string DateString = Date.ToString("yyMMdd");
string FilePath = (FolderPath + DateString);
DirectoryInfo FilesToLookThrough = new DirectoryInfo(FilePath);
if (FilesToLookThrough.Exists)
{
foreach (var MyFile in FilesToLookThrough.EnumerateFiles("*.dat", SearchOption.AllDirectories))
{
if (MyFile.LastAccessTime >= BeginningDate)
{
Console.WriteLine(MyFile.FullName);
}
}
}
}
}

据我所见,这首先获取所有文件,然后遍历所有文件并打印出来最后访问时间大于开始日期的所有文件。

它们是 C# 中的一种方法,可以从文件中提取信息而不是将其存储在列表中吗?还是我必须从头开始构建程序?

最佳答案

你的问题不是很清楚,但看看你的代码,以及你想要实现的目标,我建议你摆脱让你浏览日期文件夹的循环。只需使用每个顶级文件夹下的“AllDirectories”选项。它是递归的,所以它会向下遍历尽可能多的层次。

TimeSpan BeginningTime = DateTime.Now.TimeOfDay;
DateTime BeginningDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
DateTime EndingDate = DateTime.Now;
string[] FoldersToLookAt = { @"e:\", @"e:\Kodak Images\", @"e:\images\", @"e:\AFSImageMerge\" };
foreach (string FolderPath in FoldersToLookAt)
{
FilesToLookThrough = new DirectoryInfo(FolderPath);
if (FilesToLookThrough.Exists)
{
foreach (var MyFile in FilesToLookThrough.EnumerateFiles("*.dat", SearchOption.AllDirectories))
{
if (MyFile.LastAccessTime >= BeginningDate)
{
Console.WriteLine(MyFile.FullName);
}
}
}
}

编辑:另一个答案提出了一个很好的观点,因为您正在浏览“e:\”,您可能不需要浏览其他“FoldersToLookAt”,因为无论如何都会搜索它们。您最终可能会看到同一文件的多个列表。如果去掉它们,它会运行得更快。

您看,您的代码一开始就非常接近。使用这种方法,您可以切断整个循环,“AllDirectories”搜索选项将确保您递归地查看所有子文件夹。您还可以防止您的组织决定不将内容存储在以日期等命名的文件夹中,现在您的程序的运行时间仅与文件数量成正比。

现在,为了获得额外的荣誉,可以通过不对每个项目使用 Console.WriteLine 来实现另一项重大的性能改进。更快的方法是使用 StringBuilder,然后在最后吐出结果。

// At the top of your program
StringBuilder sb = new StringBuilder();
// BeginningTime, BeginningDate, etc...

// Before the first loop
Console.WriteLine("Working...");

// Inside the very inner if, where your Console.WriteLine was
sb.AppendLine(MyFile.FullName);


// After the end of the outer loop
Console.WriteLine(sb.ToString());

为什么这会让它变得更好?写入控制台是出了名的慢,它实际上涉及将 Windows 发送到内核模式并返回,它真的非常慢。做一次,事件有更大的文本 block ,比做很多次要快得多。现在,为什么要使用 StringBuilder 而不是仅仅做一个好的旧的:

string output;

for(...)
{
output += filename + Environment.NewLine;
}

在 C# 中,将两个字符串相加会创建一个新字符串。一遍又一遍地这样做也很慢,尤其是当新字符串变大时。 StringBuilder 只是维护所有字符串的列表,并创建一个新缓冲区并在您调用 ToString() 时将它们全部复制一次。

关于c# - EnumerateFiles() 如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16047001/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com