我有一些应用需要扫描所有试图识别某些特定内容的文件。但我真的怀疑这是否是扫描计算机中所有单元/目录/文件的最佳方法。这是代码: 要检查单位是否是我正在做的固定量:
procedure TForm1.MapUnits;
var
Drive: char;
begin
for Drive:= 'A' to 'Z' do
begin
case GetDriveType(PChar(Drive + ':/')) of
DRIVE_FIXED:
MapFiles(Drive + ':\');
end;
end;
end;
MapFiles是:
procedure TForm1.MapFiles(DriveUnit: string);
var
SR: TSearchRec;
DirList: TStringList;
IsFound: Boolean;
i: integer;
begin
DirList := TStringList.Create;
IsFound:= FindFirst(DriveUnit + '*.*', faAnyFile, SR) = 0;
while IsFound do
begin
if ((SR.Attr and faArchive) <> 0) and (SR.Name[1] <> '.') then
begin
ScanFile(DriveUnit + SR.Name);
end;
if ((SR.Attr and faDirectory) <> 0) and (SR.Name[1] <> '.') then
begin
DirList.Add(DriveUnit + SR.Name);
end;
IsFound := FindNext(SR) = 0;
end;
FindClose(SR);
// Scan the list of subdirectories
for i := 0 to DirList.Count - 1 do
MapFiles(DirList[i] + '\');
DirList.Free;
end;
请注意这个方法我正在使用将子目录列表添加到TStringList中,在完成所有主目录之后,我记得在MapFiles中,但现在传递子目录。这个可以吗? 并打开找到的文件(ScanFile)我正在做:
procedure TForm1.ScanFile(FileName: string);
var
i, aux: integer;
MyFile: TFileStream;
AnsiValue, Target: AnsiString;
begin
if (POS('.exe', FileName) = 0) and (POS('.dll', FileName) = 0) and
(POS('.sys', FileName) = 0) then
begin
try
MyFile:= TFileStream.Create(FileName, fmOpenRead);
except on E: EFOpenError do
MyFile:= NIL;
end;
if MyFile <> NIL then
try
SetLength(AnsiValue, MyFile.Size);
if MyFile.Size>0 then
MyFile.ReadBuffer(AnsiValue[1], MyFile.Size);
for i := 1 to Length(AnsiValue) do
begin //Begin the search..
//here I search my particular stuff in each file...
end;
finally
MyFile.Free;
end;
end;
end;
那么,我这样做是正确的吗?谢谢!
答案 0 :(得分:3)
我的评论:
SR.Name[1] <> '.'
测试了两次。你应该能够这样做一次。SR.Name[1] <> '.'
的测试存在缺陷。是的,它会找到'.'
和'..'
,但它也会找到'.svn'
和'.....'
,依此类推。您需要使用'.'
和'..'
来测试相等性。*.*
,使用*
DirList
保护try/finally
。ReadBuffer
可能会抛出异常。你准备好了吗?您可能最好将try/except
放在整个读取操作中,而不仅仅是打开文件。SameText(ExtractFileExt(FileName), Extension)
。