![]() |
Tail Funktionalität
Hallo Leute,
Es kennen doch von euch sicher viele die Programme "Tail for Win32", "WinTail" oder unter Linux "tail". Genau diese Funktionalität will ich in meinem Programm auch implementieren. Falls jemand die Programme nicht kennt: Diese Programme öffnen eine Datei und zeigen automatisch neue Zeilen an die nach dem Öffnen in die Datei geschrieben wurde. Am besten vorstellbar bei Log Dateien: Wenn eine neue Zeile vom Programm geloggt wird dann kann man diese sofort sehen und muss nicht die Log-Datei neu öffnen. Meine Frage ist jetzt wie ich so etwas am besten realiesieren könnte. Jedesmal mit LoadFromFile die Datei neu laden und dann auf Änderungen überprüfen ist glaub ich keine gute Lösung. |
Re: Tail Funktionalität
Du könntest in regelmäßigen Abständen die Werte der Dateigröße und 'Zuletzt geändert am' auf Änderung prüfen.
Erst wenn sich diese Werte verändert haben wird die Datei neu geladen und auf den Inhalt geprüft. Es gab aber auch mal eine Komponente namens "FileWatcher", ich glaub hier aus der DP. Evtl. könnte man da mal nachschauen, wie die die Änderungen feststellt. |
Re: Tail Funktionalität
.. hier ein ähnlicher Ansatz:
Zitat:
![]() Grüße Klaus |
Re: Tail Funktionalität
Sollte mt Hilfe eines FileStreams funktionieren.
Btw. Tail zeigt den Schluss ( letzte n-Zeilen an) |
Re: Tail Funktionalität
Hi,
Stichwort: FindFirstChangeNotification, z.B. implementiert in ATFileNotification (Komponente). Gruß Assertor |
Re: Tail Funktionalität
Also ich fass es mal kurz zusammen:
* Sagen wir mal jede Sekunde die Dateigröße überprüfen. * Wenn die Dateigröße kleiner geworden ist (sollte eigentlich nicht vorkommen) -> Datei komplett neu einlesen * Wenn die Dateigröße größer geworden ist dann über den Filestream die letzten Änderungen einlesen (Post #3) Dies klingt für mich mal ganz gut (Hätte ich eigentlich auch selbst drauf kommen können :oops: ). Die Methode sollte dann sogar über ftp funktionieren :mrgreen: . Zitat:
|
Re: Tail Funktionalität
So hab das jetzt kurz probiert und bin gleich mal auf ein Problem gestoßen:
Im Projekt Project1.exe ist eine Exception der Klasse EFOpenError mit der Meldung 'Datei C:\Testlogdatei.log kann nicht geöffnet werden. Der Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen Prozess verwendet wird' aufgetreten. Die Log-Datei wird vom Server exklusiv exklusiv geöffnet (kann ich nicht ändern). Deswegen kann mein Programm darauf nicht zugreifen. Der Witz ist aber das z.b. WinTail es schafft die Datei trotzdem auszulesen. Wie macht WinTail das? |
Re: Tail Funktionalität
Es gibt hier schon ein paar Threads zu diesem Thema "Auf Dateien zugreifen, welche geöffnet sind"
z.B. ![]() In irgendeinem hatte ich mal eine Demo gepostet, welche sobald sie erstmal Zugriff auf die Datei (vie Filehandle und mit den geltenden Zugriffs- und Sharingrechten erhalten hat, diesen immer behält und danach andere Programm normal drauf zugreifen können, da dann an den Sharingrechten vorbeigelesen wird :stupid: (ich finde nur den schon ein paar Jahre alten Thread nimmer, aber da ging's darum zu erkennen ob eine Datei vor irgendeinem Programm geöffnet ist), aber wenn ich mich nicht irre, dann würde dieser Weg dir wohl nicht viel helfen, da (glaube ich zumindestens grade) die nur der Bereich zugreifbar ist, welcher schon existierte und nichts aus Dateivergrößerungen ... müßte ich irgendwann mal schauen, ob ich das so richtig in erinnerung hab. PS: Die Zugriffsprobleme, welche du beim Lesen hast, hat das andere Programm auch, also wenn du grad dabei bist die Datei auszulesen und das andere Programm da grad was reinschreiben will ... *peng* und, wenn du Pech hast, das andere Programm macht sonstwas :stupid: |
Re: Tail Funktionalität
Du könntest einfach die Datei temporär kopieren, dann sollte das doch eigentlich klappen, oder?
müsstest du beim FTP ja sowieso, oder? |
Re: Tail Funktionalität
Zitat:
Zitat:
Zitat:
Zitat:
Das mit dem FTP ist sehr optional und war nur mal eine kleine Idee von mir. Also kann dies erstmal nach hinten gestellt werden. |
Re: Tail Funktionalität
Zitat:
wird dieser dann Problme bekommen, wenn er zugreifen will und die Datei grad von dir gegöffnet ist. leider weiß man nie genau, wie fremde Programme bei Fehlern so reagieren, bzw ob der entsprechende Programmierer diese Fehler überhaupt abgfängt und entsprechend handelt. |
Re: Tail Funktionalität
Zitat:
Jemand eine ahnung warum diese Programm es können? |
Re: Tail Funktionalität
Diese werden nicht versuchen, die Datei exklusiv zu öffnen
|
Re: Tail Funktionalität
Zitat:
Delphi-Quellcode:
S := TFileStream.Create(FileName, fmOpenRead ,fmShareDenyNone);
|
Re: Tail Funktionalität
So:
Delphi-Quellcode:
sollte es aussehen.
S := TFileStream.Create(FileName, fmOpenRead OR fmShareDenyNone);
|
Re: Tail Funktionalität
hmm da hast du recht. hab das einfach aus Post #3 kopiert.
Funktioniert aber auch mit einem OR nicht :( |
Re: Tail Funktionalität
Wenn man eine Datei öffnet kann man Sharing-Flags angeben:
a) andere Prozesse dürfen Lesen & Schreiben b) andere Prozesse dürfen nur Lesen c) andere Prozesse dürfen nur Schreiben (eher ungewöhnlich) d) andere Prozesse dürfen gar nichts (Exclusiv Modus) Der Begriff "andere Prozesse" ist etwas ungenau: man kann die gleiche Datei auch mehr als einmal öffnen und hat dann den gleichen Status wie fremde Prozesse. Ausserdem muss man angeben, ob man die Datei lesen/schreiben oder beides möchte. Wenn der Dateiersteller die Variante c) oder d) wählt, dann kann die Datei von niemand anderem gelesen werden, solange sie noch im Zugriff ist. Wenn das Öffnen wie in Betrag #15 versagt, hat man einfach Pech gehabt weil einer der anderen beteiligten Prozesse (in aller Regel der Dateiersteller) das Lesen nicht zulässt. Man müsste schon die Sperren des Betriebssystems umgehen, um da dran zu kommen. |
Re: Tail Funktionalität
Zitat:
Die Datei wird vom Service nicht mit einem Filestream sondern so aufgemacht:
Delphi-Quellcode:
Warum funktioniert meine Tail funktion bei dem nicht?
AssignFile(vFileHandle, vAktLogFilename);
if FileExists(vAktLogFilename) then Append(vFileHandle) else Rewrite(vFileHandle); Mit Notepad und so bekomme ich sie ja auch auf. Mit welchen "Rechten" wird die Datei bei der obrigen function aufgemacht? |
Re: Tail Funktionalität
Guten Morgen,
ein Blick in die Delphi Hilfe sagt uns: append : a file is opened with write-only access rewrite : if F is a text file, F becomes write-only Ich denke mal das die "alten" Routinen die Datei exclusiv öffnen. Kannst Du nur mal zum Spass prüfen, ob eine TStringList die Datei lesen kann? Grüße Klaus |
Re: Tail Funktionalität
Zitat:
Zitat:
|
Re: Tail Funktionalität
Zitat:
Bei TFileStream kann man diese Rechte selber vergeben. |
Re: Tail Funktionalität
Zitat:
Aber warum können dann andere Anwendung das File öffnen? |
Re: Tail Funktionalität
OK, hab grad nochmal nachgesehn, FILE_SHARE_READ wird doch gesetzt, also lesend kann man zugreifen.
eventuell ist ja was mit dem fmShareDenyNone nicht in Ordnung :gruebel: OK, wenn man sich das (in D7) man ansieht, dann wird Rights einfach ignoriert, wenn man die Datei nicht selber ERSTELLT.
Delphi-Quellcode:
[edit]
constructor TFileStream.Create(const FileName: string; Mode: Word; Rights: Cardinal);
begin if Mode = fmCreate then begin inherited Create(FileCreate(FileName, Rights)); if FHandle < 0 then raise EFCreateError.CreateResFmt(@SFCreateErrorEx, [ExpandFileName(FileName), SysErrorMessage(GetLastError)]); end else begin inherited Create(FileOpen(FileName, Mode)); if FHandle < 0 then raise EFOpenError.CreateResFmt(@SFOpenErrorEx, [ExpandFileName(FileName), SysErrorMessage(GetLastError)]); end; end; *weitersuch* gut, in FileOpen wird es aus Mode extrahiert, also eigentlich sollte es da klappen :gruebel: fmCreate > Sharing in Rights angeben ansonsten > Sharing mit Mode or-Verknüpfen Wer ist nur auf diesen SCH*** gekommmen (OK, wenn man fmCreate ansieht, welches $FFFF ist, dann kann man damit nix verknüpfen, aber dennoch ... dann halt immer über Rights)
Delphi-Quellcode:
zum Glück nutze ich diesen Stream nie und gehe fast immer direkt über die WinAPU und hatte da noch keine Probleme :angel2:
function FileOpen(const FileName: string; Mode: LongWord): Integer;
{$IFDEF MSWINDOWS} const AccessMode: array[0..2] of LongWord = ( GENERIC_READ, GENERIC_WRITE, GENERIC_READ or GENERIC_WRITE); ShareMode: array[0..4] of LongWord = ( 0, 0, FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE); |
Re: Tail Funktionalität
Zitat:
In diesem Fall konnte ich sie mit S := TFileStream.Create('C:\test.txt', fmOpenRead or fmShareDenyNone); ohne Probleme auslesen. |
Re: Tail Funktionalität
.. dann könnte man eventuell noch
FileOpen: Zitat:
Zitat:
Grüße Klaus |
Re: Tail Funktionalität
Wenn ich das richtig verstanden habe dann wird aber FileOpen und FileReads doch eh von TFileStream aufgerufen oder?
|
Re: Tail Funktionalität
Hiermit habe ich eine Datei erstellt und blockiert:
Delphi-Quellcode:
Hiermit kann ich aus der Datei lesen:
procedure TForm1.Button2Click(Sender: TObject);
begin assignFile(f,ExtractFilePath(ParamStr(0))+'test.txt'); rewrite(f); while true do begin writeLn(f,'test test test test test test test test'); application.processMessages; end; end;
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var fileHandle : Cardinal; buff: array[0..10] of char; i: Integer; begin fileHandle := fileOpen(ExtractFilePath(ParamStr(0))+'test.txt',fmOpenRead or fmShareDenyNone); i:=fileRead(fileHandle,buff[0],length(buff)); closeFile(fileHandle); edit1.Text:=buff+' '+IntToStr(i); end; Grüße Klaus |
Re: Tail Funktionalität
Danke für deinen Test. Dein Beispiel funktioniert bei mir auch.
Aber eins verstehe ich nicht. Die "alte" Tail function (mit FileStream) funktioniert jetzt plötzlich auch :gruebel: Eigentlich hab ich ja nichts dran geändert.
Delphi-Quellcode:
Aber gut wenn es jetzt funktioniert bin ich froh. Danke an Alle :dp:
function Tail(FileName:string; Position:Integer):string;
var S: TStream; L: Integer; begin S := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone); try S.Seek(Position, soBeginning); L := S.Size-Position; SetLength(Result, L); S.Read(Result[1], L); finally S.Free; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:00 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz