扫描所有文件/目录的正确方法

时间:2013-11-21 15:15:59

标签: delphi

我有一些应用需要扫描所有试图识别某些特定内容的文件。但我真的怀疑这是否是扫描计算机中所有单元/目录/文件的最佳方法。这是代码: 要检查单位是否是我正在做的固定量:

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;

那么,我这样做是正确的吗?谢谢!

1 个答案:

答案 0 :(得分:3)

我的评论:

  1. 您为SR.Name[1] <> '.'测试了两次。你应该能够这样做一次。
  2. 您对SR.Name[1] <> '.'的测试存在缺陷。是的,它会找到'.''..',但它也会找到'.svn''.....',依此类推。您需要使用'.''..'来测试相等性。
  3. 而不是*.*,使用*
  4. 是惯用的
  5. 您应该使用DirList保护try/finally
  6. 你的程序将永远运行。
  7. 程序几乎肯定会因内存碎片而失败。如果是32位程序并且遇到任何大文件,可能会出现正确的故障。您应该避免将整个文件加载到内存中。一次只读小块。
  8. ReadBuffer可能会抛出异常。你准备好了吗?您可能最好将try/except放在整个读取操作中,而不仅仅是打开文件。
  9. 您尝试查找具有特定扩展名的文件存在缺陷。例如,您是否将此文件视为可执行文件: MyFile.exe.blahblah.txt ?不,我不这么认为。测试扩展的正确方法如下:SameText(ExtractFileExt(FileName), Extension)