另外,我不想购买组件或使用一些免费的。
谢谢您提前的帮助!
我不知道是否有可用的Delphi代码已经实现了MFT解析器,所以你可能需要使用第三方库或自己实现。我原本想建议使用开源(GPL)NTFS Undelete,它是用Delphi编写的,但是它通过Python代码实现MFT解析,并内置了Delphi-Python桥接。
我通过使用两个线程解决了类似的问题。这样,我可以在文件从磁盘扫描时“处理”文件,同时进行处理。在我的情况下,处理速度明显比扫描速度慢,因此我还必须限制一次性在内存中的文件数量。
TMyScanThread
扫描文件结构,对于每个“匹配项”,使用Syncronize()将路径+文件添加到TList/TStringList或类似的列表中。请记住在循环内部Sleep(),以让操作系统也有一些时间。
线程的伪代码:
TMyScanThread=class(TThread)
private
fCount : Cardinal;
fLastFile : String;
procedure GetListCount;
procedure AddToList;
public
FileList : TStringList;
procedure Execute; Override;
end;
procedure TMyScanThread.GetListCount;
begin
fCount := FileList.Count;
end;
procedure TMyScanThread.AddToList;
begin
FileList.Add(fLastFile);
end;
procedure TMyScanThread.Execute;
begin
try
{ Get the list size }
Syncronize( GetListCount );
if fCount<500 then
begin
// FindFirst code goes here
{ Add a file to the list }
fLastFile := SR.Name; // Store Filename in local var
Syncronize( AddToList ); // Call method to add to list
SleepEx(0,True);
end else
SleepEx(1000,True);
finally
Terminate;
end;
end;
TMyProcessFilesThread
获取列表中最旧的条目并处理它。然后将结果输出到 DB。
该类实现了类似于访问列表的同步方法。
Syncronize() 调用的一种替代方法是使用 TCriticalSection。在线程之间实现同步通常是品味和任务的问题...
使用findfirst/findnext循环进行优化的空间并不多,因为这主要是I/O受限的:操作系统需要从硬盘中读取这些信息!
证明:编写一个简单的findfirst/findnext循环程序,对找到的文件什么都不做。重启计算机并在大型目录上运行它,记录完成所需的时间。然后再次运行它,无需重新启动计算机。您会注意到第二次运行速度明显更快,因为操作系统已经缓存了这些信息!
如果您确定正在尝试扫描的目录由于其他应用程序正在使用数据而被操作系统频繁访问(这将使目录结构信息存储在操作系统的缓存中,并且扫描不会受到I/O限制),则可以尝试使用线程并行运行多个findfirst/findnext循环。这样做的缺点是,如果目录结构尚未缓存到操作系统中,则您的算法仍受到HDD的I/O限制,而且可能比原来更糟糕,因为现在您正在进行多个并行的I/O请求,需要由同一设备处理。
当我解决同样的问题时,我选择不使用并行循环,因为应用程序的第二次运行总是要快得多,证明我受到I/O限制,无论如何优化CPU都无法解决I/O瓶颈。
RidNacs
进行比较。它是用 Delphi 编写的,使用了 findfirst/findnext 等技术... 它比 WinDirStat 快得多。 :-) - splashRidNacs
吗?我喜欢它的工作方式!现在主要问题是字体太小了。 - Edwin Yip