![]() |
Log-Datei realisieren
Hallo allerseits,
ich möchte gerne eine Log-Datei realisieren, in die mehrere Programme (bzw. mehrere Instanzen desselben Programms) ihre Einträge machen. Wie realisiere ich so etwas am besten, ohne dass die Programme sich beim Hineinschreiben in die Datei in die Quere kommen? Bisher hatte ich folgende Routine vorgesehen für das Anhängen von Log-Einträgen:
Delphi-Quellcode:
Hier kann es aber theoretisch passieren, dass zwei Programme gleichzeitig die Datei öffnen wollen und dann kracht es bei dem Programm, das einen Tick später drangekommen ist.
AssignFile(f, 'C:\Test.log');
try Append(f); Writeln(f, 'Ein Log-Eintrag'); finally CloseFile(f); end; |
Re: Log-Datei realisieren
Da gibt es viele Möglichkeiten. Eine einfache wäre zum Beispiel, dass mit CreateMutex ein benannter Mutex erzeugt wird. Mit WaitForSingleObject wartet dann ein Programm darauf, dass es Zugriff auf den Mutex kriegt. Dann schreibt es in die Datei (wie du vorgeschlagen hast), und ermöglicht mit ReleaseMutex dem nächsten Programm den Zugriff.
Zum Mitschreiben:
Delphi-Quellcode:
//Irgendwo bei Programmstart
MutexHandle:=CreateMutex(nil, false, 'MeinEindeutigerName'); //Zum loggen: WaitForSingleObject(MutexHandle, INFINITE); //warten, bis kein Programm mehr schreibt try AssignFile(f, 'C:\Test.log'); try Append(f); Writeln(f, 'Ein Log-Eintrag'); finally CloseFile(f); end; finally ReleaseMutex(MutexHandle); //jetzt dürfen wieder andere end; //am Ende CloseHandle(MutexHandle); |
Re: Log-Datei realisieren
Mit Mutexen hab ich bisher noch keinerlei Erfahrungen gemacht (wird daher höchste Zeit!), aber hört sich auf jeden Fall gut an! Vielen Dank schonmal.
Was hat denn der Parameter "MeinEindeutigerName" genau für eine Bewandnis? EDIT: Achja: was ich vergaß zu erwähnen, die mehreren Instanzen einer Anwendung laufen in meinem Fall leider auf verschiedenen Rechnern über Netzlaufwerk und sollen auf diesem Wege auch auf die Log-Datei zugreifen. In dem Fall bringt einen ein Mutex ja nicht weiter, oder? Das würde ja nur für ein und derselben Maschine gelten. |
Re: Log-Datei realisieren
Nun, alle Programme brauchen ja ein Handle zum gleichen Mutex, denn sonst funktioniert die Synchronisation nur mit mehreren Threads im gleichen Prozess. Und Windows bietet eben die Möglichkeit, dass ein Programm den Mutex eines anderen Programms öffnet, sofern der Mutex einen Namen hat.
Wenn es andererseit ein anderes Programm gibt, dass unbeabsichtigt den gleichen Namen verwendet, führt das zu Problemen. |
Re: Log-Datei realisieren
Wie in meinen oberen Post hineineditiert, lässt sich mein Problem wohl eher doch nicht über ein Mutex lösen, oder?
|
Re: Log-Datei realisieren
Kannst du nicht ins Eventlog von Windows deine Logs eintragen?
|
Re: Log-Datei realisieren
Also im Netzwerk scheiden Mutexe schonmal aus. Das einzige, was mir noch einfällt, wäre ein Log-Server, mit dem über Named Pipes kommuniziert wird - die funktionieren nämlich im Netzwerk. Aber ein Server für Logs ist unelegant und unpraktisch.
|
Re: Log-Datei realisieren
Zitat:
|
Re: Log-Datei realisieren
Am Einfachsten und Sichersten ist, wenn die Datei selbst das Mutex ist.
Wenn Process A die Datei exklusiv offen hat, müssen alle anderen Prozesse warten, bis die Resource (die Datei) wieder verfügbar wird. Sobald A die Datei wieder schliest, gewinnt der schnellste Prozess, u.s.w. Dazu gibt es in der Code-Library schon eine fertige Klasse: ![]() Das funktioniert übrigens auch im Netzwerk. |
Re: Log-Datei realisieren
@ shmia,
mich hat deine Klasse sehr interssiert und ich habe es mir angeschaut. Erst einmal mein Respekt für deine Arbeit hierzu und das zur Verfügung stellen des Sources. :thumb: Leider bekomme ich das Testprojekt nicht kompiliert. In dem Source-Abschnitt wo du das GetTickCount-Problem (wegen dem "neureseten") umgehst, erscheint bei mir eine Fehlermeldung: [DCC Fehler] FileStreamUtils.pas(281): E2003 Undefinierter Bezeichner: 'SFOpenError'
Delphi-Quellcode:
Ich verwende D2007 Prof unter Vista 32 Bit.
error := GetLastError;
curtime := GetTickCount; if ((curtime - starttime) >= timeout) or ((error<>ERROR_SHARING_VIOLATION) and (error<>ERROR_LOCK_VIOLATION)) then raise EFOpenError.CreateFmt(SFOpenError+#13#10+ //<-- Fehlermeldung SysErrorMessage(error), [FileName]); Ich kann die Fehlermeldung nun leider nicht auflösen... Weißt du vllt. was hier schief läuft? Evtl. mit etwas Erläuterung zu genau dieser Zeile 281 (raise...)? Denn genau diese Stelle kapier ich eben nicht... (vermutlich kennt Vista das nicht mehr) Danke! //Edit: Habe die Lösung selbst gefunden. :-D Liegt an der Delphiversion (vor Delphi 6) Ab den Delphi 6-Versionen wurden einige Konstanten von Borland in die RtlConsts Unit "verschoben". Man muss also unter der Uses-Klausel noch die "RtlConsts" mit aufnehmen. @ shmia, evtl. den Hinweis mit in deinen Code aufnehmen? |
Re: Log-Datei realisieren
Zitat:
warum versuchst du nicht das Eingachste: die Logdatei exklusiv zu öffen. Das kann immer nur ein Programm, ein anderes muss es später nochmal versuchen. Gruss Reinhard |
Re: Log-Datei realisieren
ohne Stream gehts genauso ... einfach versuchen die Datei exklusiv zu öffnen
Delphi-Quellcode:
tja und wenn's nich geht, dann halt 'ne Weile versuchen
AssignFile(F, LogFile);
FileMode := fmOpenReadWrite or fmShareExclusive; {$I-} Append(F); WriteLn(F, S); If IOResult <> 0 Then <<ging nich>>; CloseFile(F); {$I+}
Delphi-Quellcode:
soooo, und jetzt noch 'ne Zeitbegrenzung und so'n Zeugs rein ... fertsch (denk'sch ma)
AssignFile(F, LogFile);
FileMode := fmOpenReadWrite or fmShareExclusive; Try Repeat {$I-} Append(F); {$I+} Sleep(10); Until IOResult = 0; WriteLn(F, S); Finally CloseFile(F); End;
Delphi-Quellcode:
OK, als WinAPI sieht's och nett aus ^^
Function AddLog(Const LogFile, S: String; TimeOut{ms}: LongWord = 3000): Boolean;
Var F: TextFile; C: LongWord; M: Byte; Begin Result := False; M := FileMode; FileMode := fmOpenReadWrite or fmShareExclusive; AssignFile(F, LogFile); Try C := GetTickCount; While True do Begin {$I-} Append(F); {$I+} If IOResult = 0 Then Break; If GetTickCount - C > TimeOut Then Exit; //Application.ProcessMessages; Sleep(10); End; WriteLn(F, S); Result := True; Finally CloseFile(F); FileMode := M; End; End; If not AddLog('a.log', 'irgendwas muß rein') Then Error...
Delphi-Quellcode:
[add]
Function AddLog(LogFile, S: String; TimeOut{ms}: LongWord = 3000): Boolean;
Var H: THandle; C: LongWord; Begin Result := False; S := S + #13#10; C := GetTickCount; Repeat H := CreateFile(PChar(LogFile), GENERIC_WRITE, 0, nil, OPEN_ALWAYS, 0, 0); If H <> INVALID_HANDLE_VALUE Then Begin SetFilePointer(H, 0, nil, FILE_END); WriteFile(H, S[1], Length(S), C, nil); CloseHandle(H); Result := True; Exit; End; //Application.ProcessMessages; Sleep(10); Until GetTickCount - C > TimeOut; End; ich sollt vielleicht ma weniger nebenbai chatten ... da is doch plötlich 'nen neuer Beitrag drin und sogar mit RedBox ^^ [edit] immer diese Rechtschreibfehler :wall: |
Re: Log-Datei realisieren
Hallo,
nur so aus der Hüfte geschossen... wenn das exklusive Öffnen nix is, dann vielleicht nen kleinen Server aufsetzen, in dem per POST oder so die Logmeldungen gesendet werden. Ist natürlich aufwendiger, als "nur" ne Prozedur zu schreiben. Dann wäre auch das Dateiformat und der Speicherort gekapselt. Vielleicht läuft ja schon ein Apache oÄ. And ein paar Zeilen PHP... Aber wenn denn schon von verschiedenen Programmen auf verschiedenen Rechnern Logmeldungen zentral gesichert werden sollen... Gruß Andreas |
Re: Log-Datei realisieren
Hallo
ich hätte auch noch eine grundsätzliche idee: Parallele schreibzugriffe schreiben in temporäre weitere neue log's, welche beim nächsten schreibzugang wieder zusammengeführt werden. Die weiteren templogs', welche es nur gab, weil das Hauptlog gesperrt war, leben nur so lange, wie der nächste schreibzugriff erfolgt. Wer also das Hauptlog exclusiv öffnen kann, muss zuerst die anderen templogs auslesen und reinschreiben, dann diese templogs löschen und dann erst seine eigenen Sachen eintragen ... was meint ihr ? |
Re: Log-Datei realisieren
Noch etwas zum EventLog des Betriebssystem. Das ist eigentlich fürs betriebssystem nahe Applikationen. Wenn da jeder seinen Müll reinwirft, dann hat es ein Admi wirklich schwer...
Tip das Eventlog für eigene Programme NICHT verwenden! Besser eine Logdatei abgelegt unter "Einstellungen und Dokumente" ... :???: |
Re: Log-Datei realisieren
Der trend geht aber zum Eventlog, welcher i9n Vista deshalb stark erweitert wurde.
|
Re: Log-Datei realisieren
Hallo Leute,
ein logfile soll ja für einen bestimmten Zeitraum ein lückenloses Protokoll der Aktionen oder Ereignisse im Leben eines Programms liefern. Wenn das Protokoll wichtig ist, dann muss es lokal geschrieben werden, da bei einer instabilen Netzwerkverbindung ein Entscheidungsproblem entsteht: Muss der Client jetzt seine Arbeit einstellen. In einem Client-Server-Scenario lässt man den Server protokollieren. Schreiben die Clients eigene lokale Protokolle, dann ist eine übergreifende Auswertung durch Zusammenführen der logfiles möglich, auch wenn ich mir die Notwendigkeit gerade nicht vorstellen kann. Grüße vom marabu |
Re: Log-Datei realisieren
Erstmal Danke für die vielen Vorschläge! Ich habe mir nun anhand von himitsus Beispielen noch etwas selbst zusammengebaut. Bitte schaut euch das mal an, was es daran auszusetzen gibt. Zuvor aber noch ein paar für mich offene Fragen:
Hier mein Entwurf:
Delphi-Quellcode:
procedure TForm1.btnWriteLnClick(Sender: TObject);
var s: String; FFile: TextFile; bSuccess: Boolean; iBeginTime: Integer; iWaitTime: Integer; begin bSuccess := False; iBeginTime := GetTickCount; iWaitTime := 0; AssignFile(FFile, 'C:\Test.log'); try while (iWaitTime < 10000) do begin try Append(FFile); if (ParamCount > 0) then s := 'Programm ' + ParamStr(1) else s := 'Programm 1'; WriteLn(FFile, s); bSuccess := True; Break; except Sleep(10); iWaitTime := getTickCount - iBeginTime; end; end; if (not bSuccess) then ShowMessage('Schreiben fehlgeschlagen.') else ShowMessage('Schreiben erfolgreich.') finally if bSuccess then CloseFile(FFile); end; end; |
Re: Log-Datei realisieren
Zitat:
Delphi-Quellcode:
var
logstream: TExclusiveFileStream; s : string; begin logstream := TExclusiveFileStream.Create('C:\Test.log', 10000); try logstream.SeektoEnd; // Ans Dateiende, wir wollen anhängen if (ParamCount > 0) then s := 'Programm ' + ParamStr(1) else s := 'Programm 1'; s := s + #13#10; // Zeilenvorschub logstream.WriteBuffer(s[1], length(s)); // Daten schreiben finally logstream.Free; end; end; |
Re: Log-Datei realisieren
Zitat:
dadurch, dass du das einfach weglässt, ist dein Entwurf reiner Unsinn. Du hast weder meinen noch den Beitrag himitsus auch nur annähernd verstanden. Vielleicht solltest du mal ganz einfach anfangen "watt is eine Datei"... Gruss Reinhard |
Re: Log-Datei realisieren
Zitat:
der Einwand ist durchaus berechtigt. Ich würde das Logfile sowohl lokal als auch auf dem Server schreiben (zumindest dort natürlich ergänzt um die Client Identifikation), weil das immer noch die einfachste Variante ist. Findet man im Serverlog keine Einträge mehr, kann man im Clientlog nachschauen. Für die aktuelle Diskussion ist das ziemlich irrelevant, solang noch nicht einmal das Schreiben überhaupt funktioniert. Gruss Reinhard |
Re: Log-Datei realisieren
Zitat:
Zitat:
EDIT: Um wieder bisschen runterzukommen: watt is eine Datei??? |
Re: Log-Datei realisieren
Zitat:
Da du nix verstanden hast, lässt du das entscheidende Statement mit fmShareExclusive einfach weg. So was nenne ich beratungsresistent. Wenn du dich mal mit Dateien beschäftigen würdest, dann würdest du auch auf den Begriff "exklusiver Zugriff" stossen. Meine Meinung zum Thema: solange du diesen Punkt nicht verstanden hast, kannst du dein Problem nicht lösen - stattdessen auf Mutexe u.a. auszuweichen, ist Blödsinn, weil das das Problem nur anders einkleidet und dazu noch komplizierter ist als Datei-Zugriffe. Natürlich hast du als Jungprogrammierer das Recht, alles anders zu sehen und alle Erkenntnisse der IT mit Verachtung zu strafen. Schon ein Konkurrent weniger. Gruss Reinhard |
Re: Log-Datei realisieren
Ooohh, wie ist das schöön. :lol: Meine 10 ct zum Thema : externes Logfile z.B. Windows ist Käse. Ich würds zumindest nicht damit machen. Eigenes Logfile ist besser. Dazu würde ich aber keine Datei verwenden, sondern Datenbank. Ob die auf einem Server liegt oder lokal, das ist wohl nicht so wichtig. Notfalls muss sie eben regelmäßig lokal gesichert werden. Das gilt natürlich auch für die Daten an sich. Die sind schließlich wichtiger, als ein gesichertes Logfile ohne Daten. :mrgreen: Man könnte die zu protokollierenden Sachen auch in die vorhandene Datenbank schreiben und basta. Aber je nachdem, was da wie reingeschrieben wird kann es durchaus sein, dass das Logfile bzw. die Tabelle (viel) größer wird, als die vorhandenen Daten. In einem Programm protokolliere ich z.B. jede gedruckte Zeile. Das aber immer mitzusichern wäre völlig überdimensioniert. Für den Fall der Fälle sollte man das zwar schon mal sichern, aber doch nicht dauernd. Obwohl, ich schreibe hier über Datensicherung etc. und das ist wohl sowieso eher von untergeordneter Bedeutung. :P
|
Re: Log-Datei realisieren
das mit fmShareExclusive wurde ja schon angesprochen,
aber gern nochmals - dieses sorgt dafür daß NUR Einer zur selben Zeit die Datei öffnen kann und nicht Mehrere. ups, ja stimmt ... ohne TimeOut wird die Schleife ja nicht verlassen, bevor die Datei nicht geöffnet wurde, also kein Problem, aber mit TimeOut sollte man die mögliche Exception bei CloseFile natürlich auch abfangen, also {$I-} CloseFile(F); {$I+}. Und was das Arbeiten mit Exceptionen angeht, klar ist es möglich, aber hier gab's schonmal ein Streitgespräch darüber, ob man überhaupt absichtlich Exceptionen auslösen soll, um den Programmablauf zu steuern und da meinten die Meisten berechtigt nein. Zitat:
denn wenn ein anderer Prozess grad noch in ein TempLog reinschreibt, dann gibt es bestimmt Probleme wenn plötzlich gleichzeitig jemand anderes versucht diesen auszulesen (um ihn in den HauptLog einzutragen). im Prinzip eine nette Lösung, aber da es sich hier nur um kurzzeitige Sperrungen des HauptLogs handelt (eie Zeile einzufügen dauert ja nicht lange), wäre der Aufwand wohl eher zu groß. Sowas würde sich mehr für Dinge lohnen wo die Sperrung viel zu lange zum Warten dauert. Alternativ könnte man auch im Programm sowas wie eine Warteliste anlegen, wo man die Logeinträge einfügt und welche dann bei nächster Gelegenheit in die Logdatei eingetragen werden. |
Re: Log-Datei realisieren
Ne, himitsu. Immer noch zu kurz gesprungen. Wer so was narrensicher und komfortabel machen will, der kommt um DB nicht rum. Es geht schließlich auch um die Nachbearbeitung. Angenommen am 5.6.2006 ist irgendwas passiert und man will wissen, was jetzt genau war. Gut, dann wird eben so lange gescrollt, bis man bei dem Tag ist. Viel Vergnügen bei 100 Einträgen pro Tag. :P Da entwerfe ich mir lieber sinnvoll eine DB-Tabelle und schreibe die Zeile SELECT * FROM LOGTABLE WHERE DATUM='05.06.2006'. Es wurde auch noch nicht angesprochen, dass der Rechner / Task eindeutig gekennzeichnet werden müsste ! Wird das Programm mehrfach gestartet, dann wäre es wohl schon sinnvoll das festzuhalten. Sollte man schon auslesen. Bei mir wird das allerdings gar nicht erst zugelassen. Beim Programmstart wird eine Semaphore gesetzt.
|
Re: Log-Datei realisieren
Ich frage mich dann, warum Datenbanken so gut wie nie für Logfiles verwendet werden? BTW. Per WMI kann man auch Abfragen aif Eventlogs absetzen.
|
Re: Log-Datei realisieren
weil es vermutlich einacher ist 'ne "billige" Textdatei anzulegen, statt erst 'ne Datenbank zu implementieren.
und ich glaub kaum, daß viele sich auch nur einen einzigen Gedenkan über gleichzitigen Zugriff gemacht haben ... diese "Billig"Variante ist bestimmt seht weit verbreitet :stupid:
Delphi-Quellcode:
PS: und wie soll man "keine verbindung zur Datenbank" in dieser loggen? :roll:
AssignFile(F, 'my.log');
Append(F); WriteLn(F, S); CloseFile(F); z.B. in PHP mit defekter oder nicht vorhandener DB-Anbindung, da macht sich 'ne Textdatei doch sehr gut? (auf besondere Features wie z.B. automatische Größenanpassung muß auch keiner verzichten) ja und für den exklusiven Zugriff ist hier mal flock verantwortlich.
Code:
$Logdatei = array('Name' => 'index.log.php', 'Max' => 1048576, 'Min' => 786432,
'Zeile 1' => '<?PHP exit; /* Zeit "Benutzername" "Meldung" ' . 'Provider/IP:Port Methode:Link Postdaten Browser */ ?>'); function AddLog($S) { global $Meldungen, $BenutzernameAnzeige, $Logdatei; $H = gethostbyaddr($_SERVER['REMOTE_ADDR']); $S = date('d.m.Y H:i:s', time()) . "\t\"" . addslashes($BenutzernameAnzeige) . "\"\t\"" . addslashes($S) . "\"\t" . (($_SERVER['REMOTE_ADDR'] != $H) ? $H : 'unbekannt') . '/' . $_SERVER['REMOTE_ADDR'] . ':' . $_SERVER['REMOTE_PORT'] . "\t" . $_SERVER['REQUEST_METHOD'] . ':' . $_SERVER['VHOST'] . $_SERVER['REQUEST_URI'] . "\t" . serialize($_POST) . "\t" . "\"" . addslashes($_SERVER['HTTP_USER_AGENT']) . "\"\r\n"; @touch('./' . $Logdatei['Name']); @chmod('./' . $Logdatei['Name'], 0660); $Datei = @fopen('./' . $Logdatei['Name'], 'r+'); if ($Datei) { @flock($Datei, LOCK_EX); @fseek($Datei, 0, SEEK_END); $i = @ftell($Datei); if (($i == 0) || ($i > $Logdatei['Max'] - strlen($S))) { $i -= $Logdatei['Min'] - strlen($Logdatei['Zeile 1'] . "\r\n") - strlen($S); @fseek($Datei, 0); while (($i - @ftell($Datei) > $Logdatei['Min']) && (@fgets($Datei) !== false)) ; $i = @ftell($Datei); @fseek($Datei, 0); @fputs($Datei, $Logdatei['Zeile 1'] . "\r\n"); $k = @ftell($Datei); while (($t = @fgets($Datei)) !== false) { $i = @ftell($Datei); @fseek($Datei, $k); @fputs($Datei, $t); $k = @ftell($Datei); @fseek($Datei, $i); } @ftruncate($Datei, $k); @fseek($Datei, $k); } @fputs($Datei, $S); @flock($Datei, LOCK_UN); @fclose($Datei); } else $Meldungen[] = '*Logdatei konnte nicht geöffnet werden.'; } |
Re: Log-Datei realisieren
Zitat:
P.S.: kann sein, dass das angesprochene nur in der Vollversion geht und deshalb nicht so bekannt ist. |
Re: Log-Datei realisieren
senfe auch noch einen dazu und gebe hansa absolut recht.
10 -> n user in einem programm mit 2000 transaktions etc. am tag, wie soll man das noch sinnvoll ohne db überwachen, kontrollieren, sichern und auswerten. der aufwand ist realtiv gering auch wenn's nur ein einzelner user werden soll. lokale files, na ja, es soll ja auch noch lokale .ini's geben :wink: |
Re: Log-Datei realisieren
Hallo zusammen,
(ich hoffe, dass meine nachfolgende Frage zu diesem Thread paßt und kein neuer Thread dafür erstellt werden braucht) Wenn man nun die Größe der Protokolldatei festlegen will/muss, wie sollte man da am besten vorgehen? Die Protokolldatei jedes mal in z.B. eine TStringList laden und wenn eine vorgegebene Größe erreicht ist, dann einfach einen festen "Block" (z.B. die ersten 20000 Zeilen) löschen? Dann hätte man immer noch eine gewisse Historie. (das wäre dann quasi eine selbst reorganisierende Datei) Eine andere Möglichlkeit wäre noch, wenn die Protokolldatei die vorgegebene Größe erreicht hat, dann diese Datei einfach umzubenennen und die Protokollierung in eine neue und damit "leere" Protokolldatei fortzusetzen. |
Re: Log-Datei realisieren
Hallo Jürgen,
ich würde an Hand von Erfahrungswerten ein Zeitintervall bestimmen, nach dessen Ablauf automatisch auf eine neue Protokolldatei umgestellt wird. Grüße vom marabu |
Re: Log-Datei realisieren
Hallo marabu,
so einfach?! :-D :wall: Ehrlich gesagt, an diese Variante hatte ich noch gar nicht gedacht. Ich werde das bei mir jetzt auch genauso ändern, dass ein eigenen Ordner (Protokollierung) innerhalb der Anwendung angelegt wird. Dann wird für jeden Monat eine Protokolldatei geschrieben. Und dann noch einen "Protokoll-Viewer" basteln. Fertig ist's. Danke und ein schönes Wochenende! |
Re: Log-Datei realisieren
also in meiner PHP-Version ist es so gelöst, das bei Erreichen einer maximalen Dateigröße die Datei bis zum Minimum(Dateigröße) alte Einträge entfernt werden.
(hab mir das so einfallen lassen, da in dem Projekt seltener Einträge vorgenommen werden und eh nur die Einträge der näheren Vergangenheit interesant sind) und jedesmal die Datei komplett einzulesen wäre auch nicht grad optimal. (verbraucht nur unnötig Resourcen und Zeit) |
Re: Log-Datei realisieren
Trotz der Einwände bleibe ich hier bei der Ausgangsfrage :
Zitat:
|
Re: Log-Datei realisieren
Zitat:
Also frage ich nochmal: was bewirkt die Zeile
Delphi-Quellcode:
genau? Was ist anders, wenn ich die Zeile einfach weglasse? Mein Programm verhält sich wie gesagt genauso...
FileMode := fmOpenReadWrite or fmShareExclusive;
|
Re: Log-Datei realisieren
Zitat:
|
Re: Log-Datei realisieren
per Default ist MileMode nur auf fmOpenReadWrite gesetzt (in der Unit System)
also werden Dateien damit nicht exlusiv geöffnet. Zitat:
Zitat:
Zitat:
versuch doch einfach mal eine Datei mehrmals zu öffnen. Zitat:
Zitat:
Zitat:
aber de Witz Dabei, ich hab es eben selbst mal ausprobiert und war "geschockt" im Delphi 7 hier wird die Datei bei Schreibzugriff (Rewrite oder Append) immer im exklusiven Modus geöffnet, selbst wenn der nicht angegeben ist. Und besonsters geschockt war ich, als ich selber angegeben hab, daß mit Sharing-Rechten (nicht Exklusiv) geöffnet werden sollte :shock: Ich würde das jetzt mal ganz einfach als Delphifehler auslegen und dazu raten dieses lieber nicht auszunutzen/vorauszusetzten (wer weiß ob/wann das mal repariert wird/wurde) eigentlich müßte das Erste ohne Exception durchlaufen und das Zweite wie gewollt bei Append(F2); eine Exception auslösen.
Delphi-Quellcode:
Var F, F2: TextFile;
Begin // testdatei erstellen AssignFile(F, 'test.txt'); Rewrite(F); CloseFile(F); //FileMode := fmOpenReadWrite or fmShareDenyNone; // mit sharing-rechten AssignFile(F, 'test.txt'); Append(F); AssignFile(F2, 'test.txt'); Append(F2); CloseFile(F2); CloseFile(F); FileMode := fmOpenReadWrite or fmShareExclusive; // exklusiv AssignFile(F, 'test.txt'); Append(F); AssignFile(F2, 'test.txt'); Append(F2); CloseFile(F2); CloseFile(F); End; |
Re: Log-Datei realisieren
Zitat:
Wie dem auch sei: danke himitsu, dass du der Sache auch mal auf den grund gegangen bist! So stellt sich das alles für mich in einem ganz neuen Licht dar! Wenn man wirklich davon ausgeht, dass es sich bei diesem Verhalten um einen Delphi-Fehler handelt, dann ergibt das explizite Umstellen (und Rückstellen!!!) des FileMode durchaus einen Sinn, das sehe ich absolut genau so! Seht ihr, man kann mich durchaus überzeugen (so viel zum Thema "Jungprogrammierer" und "Erkenntnisse der IT"...). |
Re: Log-Datei realisieren
Zitat:
FileMode ist leider eine Progamminterne Variable und wird in allen nachfolgenden Reset/Rewrite/Append-Aufrufen werwendet. Wenn also irgendwo anders im Programm wieder eine Datei geöffnet wird, dann wäre es besser wenn man da den alten Wert wiederherstellt, da es da sonst zu problemen kömmen kann (wenn dort ein anderer oder der Standardwert benötigt wird) nja, das Schlimme daran ist eigentlich daß man aufgrund dieses Fehlers keine Dateien mehrfach öffnen kann, selbst wenn man wöllte :wall: (na ja, zum Glück hab ich mich da komplett auf die WinAPI umgestellt und dort läuft alles wie gewünscht ^^) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:26 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