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.