Einzelnen Beitrag anzeigen

Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.768 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Tail Komponente

  Alt 12. Jan 2012, 01:16
Gute Nacht,

mit Komponentenentwicklung habe ich noch nichts gemacht - daher nur eine Klasse:

Nachteil an dieser Klasse, der FileStream bleibt die ganze Zeit erhalten,
daher wird es nicht möglich sein, die LogDatei zu löschen oder kürzen.

Habe auf die Schnelle keine Möglichkeit gefunden- die Filegröße auszulesen ohne die Datei zu öffnen.

edit: output ist auch noch nicht synchronisiert.

Grüße
Klaus

Delphi-Quellcode:
unit tail;

interface
uses
  classes;

type
  TTail = class(TThread)
    private
      FOutput: TStrings;
      FLastFilePos: LongWord;
      FLastFileSize: LongWord;
      FFileName: String;
      FThreadWait : Boolean;
      FThreadWaitingState: Boolean;
    protected
      procedure Execute; override;
    public
      procedure pTailLogFile(sLogFile: String;output:TStrings;bAutostart: Boolean = false);
      procedure pTailStart;
      procedure pTailStop;
      procedure pTailPause;
      procedure pTailResume;
      constructor create;
      destructor Destroy; override;

  end;

implementation
uses
  sysUtils;

constructor TTail.create;
begin
  inherited create(true);
end;

destructor TTail.Destroy;
begin
  FThreadWait := true;

  inherited destroy;
end;

procedure TTail.pTailLogFile(sLogFile: string;output: TStrings; bAutostart: Boolean = False);
begin
  FFileName := sLogFile;
  FOutput := output;
  if fileExists(FFileName) then
    begin
      if bAutostart then
        begin
          pTailStart;
        end;
    end
  else
    raise Exception.Create(format('%s not found',[FFileName]));
end;

procedure TTail.pTailStart;
begin
  if self.Suspended then
    begin
      FLastFileSize := 0;
      FLastFilePos := 0;
      FThreadWait := false;
      self.Start;
    end;
end;

procedure TTail.pTailStop;
begin
  self.Terminate;
end;

procedure TTail.pTailPause;
begin
   FThreadWait := true;
end;

procedure TTail.pTailResume;
begin
  FThreadWait := false;
end;

procedure TTail.Execute;
var
  fileStream : TFileStream;
  currentFileSize : LongWord;
  dataBuffer : TMemoryStream;
  s: String;
begin
  while not terminated do
    begin
      if FThreadWait then
        begin
          sleep(50);
          FThreadWaitingState := true;
        end
      else
        begin
          if fileExists(FFileName) then
            begin


              try
                fileStream := TFileStream.Create(FFileName, fmOpenRead or fmShareDenyNone);
              except
                on E:Exception do
                  FOutput.Add(E.Message);
              end;

              try
                FThreadWaitingState := false;
                currentFileSize := fileStream.size;
                if currentFileSize > FLastFileSize then
                  begin

                    FLastFileSize := currentFileSize;
                    fileStream.Seek(FLastFilePos,soFromBeginning);

                    dataBuffer := TMemoryStream.Create;
                    try
                      dataBuffer.CopyFrom(fileStream,currentFileSize - FLastFilePos);
                      FLastFilePos := currentFileSize;
                      dataBuffer.seek(0,soFromBeginning);
                      setString(s,pChar(dataBuffer.memory),dataBuffer.Size div sizeOf(Char));
                      if s <> 'then
                        FOutput.Add(s);
                    finally
                      dataBuffer.Free;
                    end;

                  end
                else
                  if currentFileSize < FLastFileSize then
                    begin
                      FLastFileSize := 0;
                      FLastFilePos := 0;
                    end;
              finally
                fileStream.Free;
              end;
            end
          else
            sleep(100);

        end;
    end;
end;

end.
edit:
*logfile ist von tail nun nicht mehr permanent geöffnet.
*tail läuft weiter wenn die Datei gelöscht wird und anschließen mit gleichem Namen neu erstellt wird.
*tail setzt die Ausgabe der Datei fort, wenn die Datei temporär nicht erreichbar war
- wenn die Datei gekürzt wird - kommt tail mit den Dateipositionen durcheinander, darum wird die ganze Datei nochmals ausgelesen.
Klaus

Geändert von Klaus01 (12. Jan 2012 um 23:37 Uhr)
  Mit Zitat antworten Zitat