Delphi-PRAXiS
Seite 5 von 5   « Erste     345   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Log-Datei realisieren (https://www.delphipraxis.net/103023-log-datei-realisieren.html)

MatthiasR 12. Nov 2007 10:18

Re: Log-Datei realisieren
 
Nach nochmaligem Studiums der Delphi-Hilfe möchte ich einfach mal ins blaue rein behaupten, dass das Verhalten sogar gewollt ist und keinen Delphi-Fehler darstellt. Aber lest selbst:
Zitat:

Zitat von Delphi-Hilfe
Die Variable gibt den Zugriffsmodus für typisierte und nicht typisierte Dateien an, die mit Reset geöffnet werden.

Unit

System

Kategorie

Ein-/Ausgabe

Delphi-Syntax:

var FileMode: Byte = 2;

Beschreibung

In Delphi legt FileMode den Zugriffsmodus fest, wenn typisierte und nicht typisierte Dateien (keine Textdateien) mit der Prozedur Reset geöffnet werden.

Der Standardwert von FileMode ist 2 (Schreib-/Lesezugriff). Wenn Sie dieser Variablen einen anderen Wert zuweisen, wird der betreffende Modus bei allen folgenden Reset-Aufrufen verwendet. In der Unit SysUtils sind eine Reihe von Zugriffsmodus-Konstanten für Dateien deklariert, die der Variablen FileMode zugewiesen werden können.

Hinweis: Setzen Sie FileMode unbedingt zurück, bevor Sie Reset für eine schreibgeschützte Datei aufrufen. Auch wenn die Datei nur gelesen werden soll, verursacht der Standardwert von FileMode (Schreib-/Lesezugriff), dass das Öffnen einer schreibgeschützten Datei fehlschlägt.

Warnung: FileMode ist als Variable deklariert, nicht als threadvar. Deshalb ist diese Variabel nicht thread-sicher.

Hier ist nur von Reset die Rede, NICHT von Rewrite oder Append. D.h. so wie ich die Sache sehe, ist die Variable "FileMode" nur für lesenden Zugriff gedacht, und da ist es ja auch sinnvoll, da lesend standardmäßig ja beliebig viele Instanzen auf eine Datei zugreifen können. Wenn man das nicht möchte, dann kann man sich mit dem vorigen Umstellen des FileMode behelfen.

Beim schreibenden Zugriff finde ich es jedoch schon sinnvoll, dass immer nur EINE Instanz auf eine Datei zugreifen kann. Und mir fällt leider auch kein sinnvolles Beispiel ein, bei dem ein andres Verhalten - so wie von dir gewünscht - einen Sinn ergibt. Kannst du mir eines nennen?

Wieder anders ist es, wenn eine Instanz schreibend, eine zweite lesend die Datei öffnen will, das müsste man fast mal ausprobieren, wie Delphi sich dort verhält, jedoch ist das für meinen Anwendungsfall ja irrelevant.

Reinhard Kern 12. Nov 2007 11:38

Re: Log-Datei realisieren
 
Zitat:

Zitat von Infect
Nach nochmaligem Studiums der Delphi-Hilfe möchte ich einfach mal ins blaue rein behaupten, dass das Verhalten sogar gewollt ist und keinen Delphi-Fehler darstellt. Aber lest selbst...

Hallo,

ich programmiere zwar schon solange Pascal wie es das gibt, aber ich würde nie behaupten, alles zu wissen - z.B. welche File Modes Delphi ohne Anweisung setzt; ich benutze praktisch ausschliesslich Win32 für File-Operationen (in dem Fall OpenFile), weil da alles einstellbar ist und Windows das dann auch so macht wie ich es wollte. Aber das nur nebenbei, zunächst bin ich ja von deiner Fragestellung ausgegangen, weil du der Meinung warst, der Code in deinem Posting Nr. 1 funktioniere nicht, aber:

Wenn das alles so automatisch funktioniert wie zuletzt in den Postings beschrieben, dann hattest du doch vom ersten Posting an überhaupt kein Problem - oder sehe ich das auch falsch?

Eine Meinung noch dazu: die Ur-Pascal-Routinen Reset usw. haben den Anschluss an die Neuzeit weitgehend verpasst, das wurde durch Ergänzungen wie FileMode auch nur unzureichend repariert - kann auch nicht sein, damals gab es noch keine Lese-, Schreibrechte usw. Ich ersetze daher alle noch vorhandenen Aufrufe bei Gelegenheit durch die BS-Aufrufe wie OpenFile, WriteFile usw., damit hätte ein grosser Teil der Diskussion garnicht entstehen können. Das würde ich auch so weiterempfehlen.

Gruss Reinhard

MatthiasR 12. Nov 2007 12:13

Re: Log-Datei realisieren
 
Zitat:

Zitat von Reinhard Kern
...ich programmiere zwar schon solange Pascal wie es das gibt, aber ich würde nie behaupten, alles zu wissen...

Deine Äusserungen von oben hinterlassen bei mir aber leider einen ganz anderen Eindruck:
Zitat:

Zitat von Reinhard Kern
...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"...

Zitat:

Zitat von Reinhard Kern
Da du nix verstanden hast, lässt du das entscheidende Statement mit fmShareExclusive einfach weg. So was nenne ich beratungsresistent.

Zitat:

Zitat von Reinhard Kern
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.

Ich warte übrigens immernoch auf eine Entschuldigung. Ich denke, das würde sich so gehören, auch wenn ich im Vergleich zu dir was die Programmiererfahrung angeht ein kleiner Fisch sein mag.
Zitat:

Zitat von Reinhard Kern
Wenn das alles so automatisch funktioniert wie zuletzt in den Postings beschrieben, dann hattest du doch vom ersten Posting an überhaupt kein Problem - oder sehe ich das auch falsch?

Nein, das siehst du nicht falsch. Das hat sich aber wie du siehst alles erst im Nachhinein herausgestellt. Auch ich war mir nicht sicher, ob mein Ansatz aus dem ersten Post der richtige ist oder ob sich dabei zwei Programme nicht doch in die Quere kommen können. Deswegen habe ich das ja gefragt. Außerdem wollte ich noch einen Lösungsansatz erfragen, für den Fall, dass zwei Programme exakt gleichzeitig in die Log-Datei schreiben wollen. Der Ansatz (kurz Schlafen legen und dann nochmals probieren) wurde mir geliefert und ich habe ihn dankend angenommen.

Für deinen Rat, vielleicht doch besser auf die Funktionen der Win32-API zurückzugreifen, bin ich dir angesichts der entstandenen Probleme und Unklarheiten jedoch dankbar. Ist vielleicht doch der bessere Weg (siehst du, ich bin ganz und gar nicht beratungsresistent!). Könntest du mir vielleicht schonmal verraten, welche Funktionen ich da für mein Vorhaben alle benötige (außer OpenFile und WriteFile)?

shmia 12. Nov 2007 12:50

Re: Log-Datei realisieren
 
Ich glaube ich hab das schon öfters geschrieben und muss es wohl immer wieder tun:
Die Funktionen AssignFile(), Rewrite(), CloseFile(), readln(), writeln() stammen aus den Anfängen von
Pascal und sind daher veraltet.
Aus heutiger Sicht sind sie sogar eine Fehlkonstruktion.
Begründung:
Dateizugriff ist eine Aufgabe der Laufzeitbibliothek und darf nicht zum Sprachumfang einer höheren Progsprache selber gehören.
Ausserdem sind diese Funktionen gepuffert was heutzutage aber ein Nachteil ist, da das OS eh schon puffert.
Also Finger weg von den alten Funktionen und stattdessen Streams verwenden!!

MatthiasR 13. Nov 2007 07:18

Re: Log-Datei realisieren
 
Zitat:

Zitat von shmia
Ich glaube ich hab das schon öfters geschrieben und muss es wohl immer wieder tun:
Die Funktionen AssignFile(), Rewrite(), CloseFile(), readln(), writeln() stammen aus den Anfängen von
Pascal und sind daher veraltet.
Aus heutiger Sicht sind sie sogar eine Fehlkonstruktion.
Begründung:
Dateizugriff ist eine Aufgabe der Laufzeitbibliothek und darf nicht zum Sprachumfang einer höheren Progsprache selber gehören.
Ausserdem sind diese Funktionen gepuffert was heutzutage aber ein Nachteil ist, da das OS eh schon puffert.
Also Finger weg von den alten Funktionen und stattdessen Streams verwenden!!

Gut, dann nehme ich das jetzt mal als Anlass, mich endlich mal etwas mit Streams auseinanderzusetzen. Habe damit halt noch keinerlei Erfahrungen gemacht, aber das kann sich jetzt ja ändern. Und bestimmt verstehe ich danach auch deine Klasse etwas besser, dann könnte ich die doch für mein Problem einsetzen :thumb:

MuTzE.Y85 7. Apr 2016 19:30

AW: Re: Log-Datei realisieren
 
Zitat:

Zitat von himitsu (Beitrag 699819)

OK, als WinAPI sieht's och nett aus ^^
Delphi-Quellcode:
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;


Hey ich hab mal ne Frage.
Auf die Art und Weise habe ich noch nie in eine Datei geschrieben, daher die Frage.

Meine Logdatei hat vor jedem Zeichen einen NUL Charakter.
Ist das normal? Bzw. geht das mit der Funktion auch anders?
Sieht sehr bescheiden aus. Man kann quasi nix lesen. :(

FarAndBeyond 8. Apr 2016 06:05

AW: Log-Datei realisieren
 
@ shmia:
Besten Dank, die Klasse kannte ich noch nicht...

Hab' bis jetzt immer 'ne TStringlist genommen, da das sehr viel einfacher ist als die Einzelbefehle...
Brauche in Kürze eh mal öfter'n MemoryStream, da bietet sich das komplette Stream-Thema ja eigentlich an.

Lemmy 8. Apr 2016 08:34

AW: Re: Log-Datei realisieren
 
Zitat:

Zitat von MuTzE.Y85 (Beitrag 1334966)
Meine Logdatei hat vor jedem Zeichen einen NUL Charakter.
Ist das normal? Bzw. geht das mit der Funktion auch anders?
Sieht sehr bescheiden aus. Man kann quasi nix lesen. :(

hört sich nach einem Unicodeproblem an. Aber warum WinAPI? Gibt es dafür einen besitmmten Grund? Schau mal ob deine Delphiversion TStreamWriter unterstützt und wenn ja dann verwende das.. Wenn ich das richtig sehe wurde das mit Delphi 2010 eingeführt...

Grüße

himitsu 8. Apr 2016 09:15

AW: Log-Datei realisieren
 
Die #0 stört nicht, aber dass der halbe Text fehlt ist vielleicht etwas schlimmer. :zwinker: (seit Delphi 2009)

Jupp, die bösen Jugendsünden bestrafen Einen immer wieder. :oops:
Einfach aus String ein AnsiString machen und aus #13#10 ein sLineBreak.

Und da wir "nette" Programmierer sind, wird auch noch aus GENERIC_WRITE, 0 ein GENERIC_WRITE, FILE_SHARE_READ.



Die WinAPI hatte hier den Vorteil, daß die Fehlerbehandlung etwas "sanfter" reagiert, also vorallem ohne Exceptions.

MuTzE.Y85 8. Apr 2016 21:47

AW: Log-Datei realisieren
 
Nun, es musste natürlich wieder schnell gehen, und das hier hatte ich mit als erstes gefunden :D

Und da der Code von himitsu war, hab ich ihn genommen.


Aktuell nutze ich den Code hier von Luckie:
Delphi-Quellcode:
function WriteLog(LogFile, LogString: String): Integer;
var
  f: TextFile;
begin
{$IOCHECKS OFF}
  AssignFile(f, LogFile);
  if FileExists(LogFile) then
    Append(f)
  else
    Rewrite(f);
  Writeln(f, LogString);
  CloseFile(f);
  Result := GetLastError();
{$IOCHECKS ON}
end;
Welcher ist denn nun besser?
Wie shmia oben schreibt sollte man solchen Code heute nicht mehr nutzen, da es bessere Wege gibt.

Zur Erklärung:
Ich schreibe ein kleines Tool um Prime95 fernzusteuern und lasse alle 30 Sekunden die Kerntemperaturen speichern. Dafür brauche ich die Logfunktion


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:18 Uhr.
Seite 5 von 5   « Erste     345   

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