Thema: Delphi Verzeichnisüberwachung

Einzelnen Beitrag anzeigen

luckystar85

Registriert seit: 21. Dez 2004
Ort: Rostock
138 Beiträge
 
Delphi 2009 Professional
 

Verzeichnisüberwachung

  Alt 17. Aug 2005, 15:45
Moin,

ich habe mir mal ein Programm geschrieben was ein vom benutzer eingestelltes Verzeichnis überwacht und bei Änderungen darin überprüft ob alle Dateien darin i.O. sind. Das wird mit Hilfe eines Threads gemacht.

Delphi-Quellcode:
procedure TcsDirThread.Execute;
var
  pBuf : Pointer;
  dwBufLen : DWORD;
  dwRead : DWORD;
  FNI : FILE_NOTIFY_INFORMATION;
  pWork : Pointer;
  sFileName : Widestring;
  dwWaitStatus : DWORD;
begin
  FhFile := CreateFile(PChar(FsDirPath),
                          FILE_LIST_DIRECTORY or GENERIC_READ,
                          FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil,
                          OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS,0);
                          
  hNotifity := FindFirstChangeNotification(PChar(FsDirPath), //Verzeichnis
                                           false, //unterverzeichnisse überwachen
                                           FILE_NOTIFY_CHANGE_FILE_NAME or
                                           FILE_NOTIFY_CHANGE_LAST_WRITE or
                                           FILE_NOTIFY_CHANGE_SIZE or
                                           FILE_ACTION_ADDED or
                                           FILE_ACTION_REMOVED or
                                           FILE_ACTION_MODIFIED);
  if (FhFile = INVALID_HANDLE_VALUE) or (FhFile = 0) then
  begin
    RaiseLastWin32Error;
    Terminate;
  end;
  if (hNotifity = INVALID_HANDLE_VALUE) then
  begin
    RaiseLastWin32Error;
    Terminate;
  end;

  dwBufLen := 65536;
  pBuf := AllocMem(dwBufLen);
  try
    while ((FindNextChangeNotification(hNotifity)) and (not terminated)) do
    begin
      Synchronize(Application.ProcessMessages);
      dwWaitStatus := WaitForSingleObject(hNotifity, 1000);
      if (dwWaitStatus = WAIT_FAILED) then
      begin
        RaiseLastWin32Error;
        Terminate;
      end;
      if (dwWaitStatus = WAIT_OBJECT_0) then
      begin
        ReadDirectoryChangesW(FhFile,pBuf,dwBufLen,true,
                              FILE_NOTIFY_CHANGE_FILE_NAME or
                              FILE_NOTIFY_CHANGE_DIR_NAME or
                              FILE_NOTIFY_CHANGE_ATTRIBUTES or
                              FILE_NOTIFY_CHANGE_SIZE or
                              FILE_NOTIFY_CHANGE_LAST_WRITE or
                              FILE_NOTIFY_CHANGE_CREATION or
                              FILE_ACTION_ADDED or
                              FILE_ACTION_REMOVED or
                              FILE_ACTION_MODIFIED,
                              @dwRead,nil,nil);
        pWork := pBuf;
        repeat
          StrMove(@FNI,pWork,12);
          PChar(pWork) := PChar(pWork)+12;
          sFileName := StringOfChar(#00,FNI.dwFileNameLength);
          StrMove(@sFileName[1],pWork,FNI.dwFileNameLength);
          FsFileName := WideCharToString(PWideChar(sFileName));
          FsFileName := copy(FsFileName,1,length(FsFileName) shl 1);
          FsReason := GetReason(FNI.dwAction);
          Synchronize(AddFileToList);
          PChar(pWork) := PChar(pBuf)+FNI.dwNextEntryOffset;
        until FNI.dwNextEntryOffset = 0;
      end;
    end;

    if (LowerCase(ExtractFileExt(FsFileName)) = '.bmp') then
    begin
      PostMessage(MainForm.Handle, Verzeichnisaenderung_bmp, 0, ProjektID);
    end;
  finally
    FreeMem(pBuf,dwBufLen);
  end;
end;
Jetzt habe ich mal eine neuen Datei angelegt und wieder gelöscht dann ist das alles kein Problem. Die Änderungen wird mit AddFileToList in eine TStringList eingefügt und kann bei bedarf angezeigt ode gespeichert werden. Anschließend habe ich mal mit TotalCommander das Dateidatum geändert und wollte mir dann mal die StringList angucken. Da trat mein Problem auf: In meiner StringList waren fast 500000 einträge. Das Speichern der Datei war möglich, dauerte natürlich sehr lange und die Datei war anchher 142 MB groß (reine Textdatei), aber das Anzeigen der StringList in TListBox mit Assign ging gar nicht mehr. Nachdem die Auslagerungsdatei auf 1,94 GB erweitert wurde, wollte mein Rechner nicht mehr.
Warum sind da sol viele Änderungen drin. Das lustige dabei ist das bis auf die ersten 2 Änderungen (Datei anlegen und löschen) immer das selbst stand (Datei wurde geändert). Immer wieder das selbe. Im Abstand von weniger als 1 sekunde. Ist das jetzt ein Problem bei mir oder ein Problem von Windows das ich umgehen muss? Wäre nett wenn ihr mir Tipps und Anregungen geben würdet.
Michael Klüber
Delphi ist was solides und besteht nicht wie C/C++ Quelltext nur aus Kommentaren.
  Mit Zitat antworten Zitat