2013-11-21 40 views
0

我有一些應用程序需要掃描所有文件,試圖識別一些特定的東西。但我真的懷疑這是否是掃描計算機中所有設備/目錄/文件的最佳方式。下面的代碼: 要檢查單元是固定容積我做:正確的方式來掃描所有文件/目錄

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; 

的映射文件是:

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

@RBA似乎不是同一種搜索。 – GolezTrol

+1

您是否遇到一些特定的問題,或者您想要檢查您的代碼?同時提示:永遠不要通過值傳遞字符串參數,特別是如果你正在遞歸。另外:你必須檢查並忽略遇到的「..」目錄。 –

+0

@FreeConsulting'SR.Name [1] <>'。'收集這些信息。以及名爲''...'的目錄等等。 –

回答

3

我的評論:

SR.Name[1] <> '.'
  1. 你測試兩次。你應該可以做到這一次。
  2. 您對SR.Name[1] <> '.'的測試存在缺陷。是的,它會發現'.''..',但它也會發現'.svn''.....'等等。您需要對'.''..'進行相等測試。
  3. 而不是*.*,它是慣用的使用*
  4. 你應該用try/finally保護DirList
  5. 您的程序將永遠運行。
  6. 該程序幾乎肯定會因內存碎片而失敗。如果它是一個32位程序,並且您遇到任何大型文件,可能會出現錯誤。您應該避免將整個文件加載到內存中。一次只讀小塊。
  7. ReadBuffer可能會引發異常。你準備好了嗎?將try/except放在整個讀取操作周圍,而不僅僅是打開文件可能會更好。
  8. 你試圖找到具有特定擴展名的文件是有缺陷的。例如,你會認爲這個文件是一個可執行文件:MyFile.exe.blahblah.txt?不,我不這麼認爲。測試擴展的正確方法如下:SameText(ExtractFileExt(FileName), Extension)
相關問題