Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Textfile nach änderung nachladen (https://www.delphipraxis.net/140352-textfile-nach-aenderung-nachladen.html)

msickel 16. Sep 2009 19:19


Textfile nach änderung nachladen
 
Hallo, ich möchte folgendes versuchen habe aber keinen richtigen Ansatzpunkt wie ich das umsetzten kann.

Ich möchte ein Textfile laden und dieses in Realtime überwachen, d.h wird eine Änderung im Textfile gemacht soll mein Programm die Änderung gleich anzeigen. Mit einem Memo habe ich das schon mal versucht ist aber unbrauchbar, wie kann man soetwas am geschicktesten lösen.

Auf Euere Vorschläge freue ich mich schon.

himitsu 16. Sep 2009 19:38

Re: Textfile nach änderung nachladen
 
Zitat:

Mit einem Memo habe ich das schon mal versucht ist aber unbrauchbar
wie was wann wo ... und vorallem warum unbrauchbar?


[dp]Datei überwachen[/dp]?

msickel 16. Sep 2009 19:46

Re: Textfile nach änderung nachladen
 
Ich habe nach dem öffnen der Datei einen Timer erzeugt und hier dann jede Sekunde das Textfile nachgeladen, hier ist es dann aber so das es stark flackert und laufend die Sanduhr kommt, zudem wird nach jedem nachladen der Cursor wieder auf den Anfang gesetzt was ein nachverfolgen der Änderungen fast unmöglich macht.

Klaus01 16. Sep 2009 19:49

Re: Textfile nach änderung nachladen
 
.. dann vergleiche doch den Inhalt vom Memo (Memo.text)
und den Inhalt der nachgeladenen Datei (StringList.Text)
und füge nur die Unterschiede in das memo ein.

Grüße
Klaus

edosoft 17. Sep 2009 01:54

Re: Textfile nach änderung nachladen
 
hi,

binde diese unit ein:
Delphi-Quellcode:
unit AutoSVNNotify;

interface

uses
  Classes, Windows, StrUtils;

type
  TAutoSVNNotify = class(TThread)
  private
    sDirName: string;
    cResFilename1: string;
    cResFilename2: string;
    cResAction: Integer;
    procedure UpdateEvent();
  protected
    procedure Execute; override;
  public
    constructor Create(sDirName: string; CreateSuspended: Boolean);
  end;
  FILE_NOTIFY_INFORMATION = record
    dwNextEntryOffset: DWORD;
    dwAction: DWORD;
    dwFileNameLength: DWORD;
  end;

implementation

uses Unit1;

{ TAutoSVNNotify }

procedure TAutoSVNNotify.UpdateEvent;
begin
  if cResAction <> FILE_ACTION_RENAMED_NEW_NAME then
    cResFilename2 := '';
  Form1.UpdateEvent(cResFilename1, cResFilename2, cResAction);
end;

procedure TAutoSVNNotify.Execute;
var
  dirHandle: THandle;
  iBuf: Pointer;
  iBufWorker: Pointer;
  iBufLen: Cardinal;
  iRead: DWORD;
  FN: FILE_NOTIFY_INFORMATION;
  s: string;
begin
  dirHandle := CreateFile(PChar(sDirName), GENERIC_READ or 1, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
  if (dirHandle = 0) or (dirHandle = INVALID_HANDLE_VALUE) then Exit;

  iBufLen := 65536;
  GetMem(iBuf, iBufLen);
  while not Self.Terminated do
  begin
    if not ReadDirectoryChanges(dirHandle, iBuf, iBufLen, True, FILE_NOTIFY_CHANGE_FILE_NAME or FILE_NOTIFY_CHANGE_DIR_NAME or FILE_NOTIFY_CHANGE_LAST_WRITE, @iRead, nil, nil) then
      Exit;

    iBufWorker := iBuf;
    repeat
      Move(iBufWorker^, FN, 12);
      s := WideCharLenToString(Pointer(Cardinal(iBufWorker) + 12), FN.dwFileNameLength);
      s := LeftStr(s, FN.dwFileNameLength div 2);
      cResAction := FN.dwAction;
      if FN.dwAction <> FILE_ACTION_RENAMED_NEW_NAME then
        cResFilename1 := s
      else
        cResFilename2 := s;

      if FN.dwAction <> FILE_ACTION_RENAMED_OLD_NAME then
        Synchronize(UpdateEvent);

      Inc(Cardinal(iBufWorker), FN.dwNextEntryOffset);
    until FN.dwNextEntryOffset = 0;
  end;
end;

constructor TAutoSVNNotify.Create(sDirName: string; CreateSuspended: Boolean);
begin
  inherited Create(CreateSuspended);
  FreeOnTerminate := True;
  Self.sDirName := sDirName;
end;

end.
und erstelle dir dann ein TAutoSVNNotify thread. inm creator stellst du direkt den pfad ein, den du überwachen willst. (also der, in dem dein textfile liegt.)

die funktion procedure TAutoSVNNotify.UpdateEvent; musst du anpassen und Form1.UpdateEvent() durch deine funktion ersetzen, an die die changes gesendet werden sollen.
cResFilename1 ist der dateiname oder der alte dateiname der datei
cResFilename2 ist der neue dateiname der datei (wird nur bei einem file rename eingesetzt)
cResAction ist die aktion

aktionen können glaub ich sein:
FILE_ACTION_REMOVED: die datei cResFilename1 wurde gelöscht
FILE_ACTION_ADDED: die datei cResFilename1 wurde neu angelegt
FILE_ACTION_MODIFIED: die datei cResFilename1 wurde geändert
FILE_ACTION_RENAMED_NEW_NAME: datei cResFilename1 wurde in cResFilename2 umbenannt
//FILE_ACTION_RENAMED_OLD_NAME [wird nie getriggert, da an dieser stelle nur cResFilename1 mit dem alten dateinamen gefüllt wird, der trigger erfolgt später bei FILE_ACTION_RENAMED_NEW_NAME, sonst wäre ja nur der alte aber nicht der neue dateiname bekannt]


was du machen musst ist also nur das verzeichnis mit der textdatei überwachen und bei jeder file_action_modified den inhalt nachladen. (natürlich werden auch für andere dateien im verzeichnis file actions übermittelt, du musst aber nur mit cresfilename1 checken, ob halt die textdatei um dies geht geändert wurde oder irgend ne andere datei)
eventuell kannst du auch die action_removed und renamed kontrollieren und den benutzer warnen oder so wenn die datei gelöscht oder "weg-umbenannt" wurde.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:38 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz