Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi ForceFile (https://www.delphipraxis.net/211068-forcefile.html)

Monday 23. Jul 2022 09:30

ForceFile
 
Es gibt ja ein ForceDirectory, aber kein ForceFile.

Deshalb habe ich eines gemacht. Ist zwar nicht spektakulär, aber für faule Menschen wie mich ;-)




ForceFile erstellt eine Textdatei, wenn sie noch nicht vorhanden ist.

Optional: Löscht und erstellt eine Textdatei, wenn sie schon vorhanden ist (z.B., wenn man den Inhalt einer vorhandenen Textdatei löschen möchte und mit einer leeren Textdatei beginnen möchte).


Delphi-Quellcode:
procedure ForceFile(dateiname: string; bereits_vorhandene_datei_trotzdem_neu_erstellen: boolean = False);
var
  f: text;
begin
{
 bereits_vorhandene_datei_trotzdem_neu_erstellen -> True.
 z.B. wenn man eine leere Datei haben will, und ein bereits vorhandener Dateiinhalt nicht mehr weiterverwendet werden soll
}
  if not FileExists(dateiname) then begin
    assignfile(f, dateiname);
    rewrite(f); //writeln(f, '');
    closefile(f);
  end;
  if bereits_vorhandene_datei_trotzdem_neu_erstellen then begin
    DeleteFile(dateiname);
    assignfile(f, dateiname);
    rewrite(f); //writeln(f, '');
    closefile(f);
  end;
end;


Beispiel:
Delphi-Quellcode:
ForceFile('bericht.txt');



Oder auch eine vorhandene Datei neuerstellen:
Delphi-Quellcode:
ForceFile('bericht.txt',True);


Man spart sich im eigentlichen Code ein paar Zeilen Code.

KodeZwerg 23. Jul 2022 12:14

AW: ForceFile
 
Delphi-Quellcode:
function MakeFile(const AFilename: string; const AOverwrite: Boolean = False; const AShowError: Boolean = False): Boolean;
const
  INVALID_HANDLE_VALUE = THandle(-1);
var
  h: THandle;
begin
  Result := False;
  if (AFilename = '') then
    Exit;
  if (AOverwrite and FileExists(AFilename)) then
    if (not DeleteFile(AFilename)) then
    begin
      if AShowError then
        ShowMessage('File deletion for "' + AFilename + '" failed.');
      Exit;
    end;
  if (not FileExists(AFilename)) then
  begin
    h := FileCreate(AFilename);
    if (h = INVALID_HANDLE_VALUE) then
      begin
        if AShowError then
          ShowMessage('File creation for "' + AFilename + '" failed.');
        Exit;
      end
      else
      begin
        FileClose(h);
        Result := True;
      end;
  end
  else
    Result := True;
end;
Eine weitere Möglichkeit.

//Edit, methode ist nun eine function und man könnte es als "if makefile('blabla.bla')" nutzen

himitsu 23. Jul 2022 20:36

AW: ForceFile
 
Delphi-Quellcode:
procedure ForceFile(dateiname: string; bereits_vorhandene_datei_trotzdem_neu_erstellen: Boolean = False);
var
  f: Text;
begin
  if not FileExists(dateiname) or bereits_vorhandene_datei_trotzdem_neu_erstellen then begin
    //DeleteFile(dateiname); // nicht nötig, weil der Inhalt wird ja eh gelöscht/überschrieben
    AssignFile(f, dateiname);
    Rewrite(f); //WriteLn(f, '');
    CloseFile(f);
  end;
end;
:stupid:


Das behebt auch das "Problemchem" mit dem doppelten Erstellen, wenn NotExist und bereits_vorhandene...
Alernativ wäre ein ELSE zwischen den IF auch eine Lösung dafür.

Uwe Raabe 23. Jul 2022 20:52

AW: ForceFile
 
Mir erschließt sich noch nicht ganz der Sinn der ganzen Aktion. Für einen Lesezugriff ist das ja eher uninteressant, eine leere Datei zu erstellen bzw. eine existierende mit einer leeren ersetzen. Für das Lesen ist doch eher wichtig ob die Datei überhaupt existiert.

Beim Schreiben hilft mir das aber auch nicht viel weiter, da kann ich dann nach dem ForceFile zwar auf das Create verzichten und ein simples OpenFile verwenden, aber der Aufwand in ForceFile erscheint mir dafür nicht wirklich angemessen.

In solchen Fällen verwende ich dann eher einen TStreamWriter, je nach gewünschten Verhalten mit Append = True oder False. Dann habe ich die Datei gleich am Wickel im Zugriff und niemand kann sie so einfach zwischen einem ForceFile und OpenFile wieder löschen.

Ich bin aber offen für Szenarien, bei denen eine solche Funktionalität sinnvoll sein kann.

Monday 24. Jul 2022 07:03

AW: ForceFile
 
@Uwe

Ich habe es verwendet für TSTringList.loadFromFile() . Da muss es die Datei schon geben. Und ich wollte nur ein einfaches Protokoll/Bericht anfertigen, das dann auch evtl. weitergeführt werden sollte.

Da finde ich den Einzeiler dann schon ganz nett, und muss nicht denn Programmablauf, mit file exists und so weiter "stören":


forcefile(datei)
Stringlist.create
StringList.loadfromFile(datei)
...

himitsu 24. Jul 2022 10:34

AW: ForceFile
 
Da du sowieso ein FileExists benutzt, warum dann nicht einfach
Delphi-Quellcode:
if FileExists(...) then SL.LoadFromFile(..);
?

Delphi.Narium 24. Jul 2022 10:49

AW: ForceFile
 
Das würd' ich dann aber noch etwas anpassen:
Delphi-Quellcode:
function ForceFile(dateiname: string; bereits_vorhandene_datei_trotzdem_neu_erstellen: Boolean = False) : Boolean;
var
  f: Text;
begin
  Result := ForceDirectories(ExtractFilePath(Dateiname));
  if Result then begin
    if not FileExists(dateiname) or bereits_vorhandene_datei_trotzdem_neu_erstellen then begin
      AssignFile(f, dateiname);
      ReWrite(f);
      CloseFile(f);
    end;
  end;
  Result := FileExists(dateiname);
end;
...
if ForceFile(datei) then begin
  Stringlist.Create;
  StringList.LoadfromFile(datei);
  ...
  StringList.SaveToFile(datei);
  StringList.Free;
end else begin
  // Fehlerbehandlung ...
end;
Bei fehlender Verzeichnisstruktur wird Deine Variante (vermutlich) scheitern, himitsus Einzeiler
Delphi-Quellcode:
if FileExists(...) then SL.LoadFromFile(..);
ebenfalls, wenn die Stringliste per SaveToFile gespeichert werden soll.

himitsu 24. Jul 2022 11:14

AW: ForceFile
 
Das ForceDirectory reicht beim Speichern.

Beim Laden ist es egal.
Die Datei ist so oder so nicht da (oder leer), egal ob man das Verzeichnis und/oder die Datei noch erstellt.
Und eine dann neue leere Datei zu laden macht auch keinen Sinn. (*1)


*1) Einzig um beim Laden bereits zu prüfen, ob die Datei später auch gespeichert werden kann,
aber auch a kann man direkt mir einem Read/Write-Schreibzugriff die Datei öffnen (ohne ihren Inhalt zu löschen) und direkt laden.

Delphi.Narium 24. Jul 2022 11:52

AW: ForceFile
 
Zitat:

Zitat von himitsu (Beitrag 1509147)
*1) Einzig um beim Laden bereits zu prüfen, ob die Datei später auch gespeichert werden kann,
aber auch a kann man direkt mir einem Read/Write-Schreibzugriff die Datei öffnen (ohne ihren Inhalt zu löschen) und direkt laden.

Mir ging's darum, am Anfang zu prüfen, ob die Datei nicht nur geladen werden kann (sofern vorhanden), sondern auch am Anfang schon (möglichst) sicherzustellen, dass sie im späteren Programmverlauf auch geschrieben werden kann.

Bei 'ner Logdatei ist's halt "blöde", wenn nach stundenlangem Programmlauf festgestellt wird, dass die Logdatei nicht geschrieben werden kann. Ist halt ärgerlich, kommt aber zuweilen schonmal im realen Leben vor.

Daher mach' ich lieber ein paar Prüfungen zuviel, als irgendwann auf die Nase zu fallen.

Wenn das ForceDirectories bereits am Anfang scheitert, weiß man, dass man nicht sinnvoll weitermachen kann, auch wenn das ForceDirectories letztlich unmittelbar vor dem SaveToFile ausreichen würde.

Natürlich ist es nicht sinnvoll eine leere Datei zuladen, Nichts in 'ner Stringliste ist halt eben Nichts in 'ner Stringliste, aber ich weiß dann schonmal sicher, dass ich Nichts habe und muss nicht mehr damit rechnen, dass ich im weiteren Programmverlauf nichtmal Nichts haben werde ;-)

Beim ForceFile weiß ich aber, dass das Verzeichis erstellt werden kann und das in dem Verzeichnis eine Datei erstellt werden kann. Man könnte die Funktion noch um eine IO-Prüfung erweiteren, so dass damit dann auch noch eventuell vorhandene Rechteprobleme, ... festgestellt werden könnten und dort einem nicht unerwarten eine Exception um die Ohren fliegt.
Delphi-Quellcode:
function ForceFile(dateiname: string; bereits_vorhandene_datei_trotzdem_neu_erstellen: Boolean = False) : Integer;
var
  f : Text;
  bOk : Boolean;
  iIOResult : Integer;
begin
  Result := 0;
  bOk := ForceDirectories(ExtractFilePath(Dateiname));
  if bOk then begin
    if not FileExists(dateiname) or bereits_vorhandene_datei_trotzdem_neu_erstellen then begin
      AssignFile(f, dateiname);
      {$I-}
      ReWrite(f);
      {$I+}
      Result := IOResult;
      CloseFile(f);
    end;
  end else begin
    Result := -MaxInt;
  end;
end;
...
iIOResult := ForceFile(datei);
case iIOResult of
  0 : begin
        Stringlist.Create;
        StringList.LoadfromFile(datei);
        ...
        StringList.SaveToFile(datei);
        StringList.Free;
     end;
  // hier ggfls. andere Werte von iIOResult gezielt abfragen und entsprechend reagieren.
  else
    // Fehlerbehandlung ...
  end;
end;
Und ja, die Frage ist, wieviel Aufwand will man da treiben?

himitsu 24. Jul 2022 12:23

AW: ForceFile
 
Man kann sich ja einfach mal den Code des LoadFromFile vornehmen und dort den Dateizugriff anpassen.
In diesem Fall also OPEN_EXISTING durch OPEN_ALWAYS ersetzen und zusätzlich auch den Schreibzugriff zu aktivieren (siehe SaveToFile).
https://docs.microsoft.com/en-us/win...#CREATE_ALWAYS

Delphi-Quellcode:
uses System.RTLConsts;

procedure TForm9.FormCreate(Sender: TObject);
var
  FN: string;
  SL: TStringList;
  FS: {TFileStream}THandleStream;
  FH: THandle;
begin
  FN := ChangeFileExt(Application.ExeName, '.txt');
  SL := TStringList.Create;
  try
    ForceDirectories(ExtractFileDir(FN));
    FH := CreateFile(PChar(FN), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ, nil,
      {OPEN_EXISTING}OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0);
    if FH = INVALID_HANDLE_VALUE then
      //RaiseLastOSError;
      raise EFCreateError.CreateFmt(SFCreateErrorEx, [ExpandFileName(FN), SysErrorMessage(GetLastError)]);
    try
      FS := THandleStream.Create(FH); // hatte der HandleStream nicht mal ein "Owns" und konnte das Handle dann selber freigeben? 
      try
        SL.LoadFromStream(FS);
      finally
        FS.Free;
      end;
    finally
      CloseHandle(FH);
    end;

    //...

    SL.SaveToFile(FN);
  finally
    SL.Free;
  end;
end;
Alternativ alles zufammenfassen und daraus nur eine "Prüfung" bauen.

Delphi-Quellcode:
procedure TForm9.FormCreate(Sender: TObject);
var
  FN: string;
  SL: TStringList;
  FH: THandle;
begin
  FN := ChangeFileExt(Application.ExeName, '.txt');
  SL := TStringList.Create;
  try
    ForceDirectories(ExtractFileDir(FN));
    FH := CreateFile(PChar(FN), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ, nil,
      {OPEN_EXISTING}OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0);
    if FH = INVALID_HANDLE_VALUE then
      //RaiseLastOSError;
      raise EFCreateError.CreateFmt(SFCreateErrorEx, [ExpandFileName(FN), SysErrorMessage(GetLastError)]);
    CloseHandle(FH);

    SL.LoadFromFile(FN);

    //...

    SL.SaveToFile(FN);
  finally
    SL.Free;
  end;
end;


Der FileHandle (FH) und FileStream (FS) ließen sich auch bis zum Ende behalten und direkt zum Schreiben benutzen.
Da kann zwischendrin auch nicht die Datei, bzw. das Schreibrecht und das Sharingrecht verschwieden, weil es die ganze Zeit bestehen bleibt.

Delphi-Quellcode:
procedure TForm9.FormCreate(Sender: TObject);
var
  FN: string;
  SL: TStringList;
  FS: {TFileStream}THandleStream;
  FH: THandle;
begin
  FN := ChangeFileExt(Application.ExeName, '.txt');
  SL := TStringList.Create;
  try
    ForceDirectories(ExtractFileDir(FN));
    FH := CreateFile(PChar(FN), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ, nil,
      {OPEN_EXISTING}OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0);
    if FH = INVALID_HANDLE_VALUE then
      //RaiseLastOSError;
      raise EFCreateError.CreateFmt(SFCreateErrorEx, [ExpandFileName(FN), SysErrorMessage(GetLastError)]);
    try
      FS := THandleStream.Create(FH);
      try
        SL.LoadFromStream(FS);

        //...

        FS.Position := 0;
        FS.Size := 0; // oder nach dem Speichern ein Truncate
        SL.SaveToStream(FS);
        //FS.Truncate; // gibt es nicht, aber Size zuweisen geht ja auch, sowie auch über das Handle
        // also FS.Size := FS.Position;
        // oder SetEndOfFile(FH);
      finally
        FS.Free;
      end;
    finally
      CloseHandle(FH);
    end;
  finally
    SL.Free;
  end;
end;

Uwe Raabe 24. Jul 2022 13:46

AW: ForceFile
 
Zitat:

Zitat von himitsu (Beitrag 1509152)
Man kann sich ja einfach mal den Code des LoadFromFile vornehmen und dort den Dateizugriff anpassen.

Etwa so?
Delphi-Quellcode:
type
  TStringsHelper = class helper for TStrings
    procedure LoadFromFile(const FileName: string); overload;
    procedure LoadFromFile(const FileName: string; Encoding: TEncoding); overload;
  end;

procedure TStringsHelper.LoadFromFile(const FileName: string; Encoding: TEncoding);
begin
  if FileExists(FileName) then
    inherited;
end;

procedure TStringsHelper.LoadFromFile(const FileName: string);
begin
  if FileExists(FileName) then
    inherited;
end;

himitsu 24. Jul 2022 14:36

AW: ForceFile
 
Ja, für das reine Abfangen der Exception, wenn die Datei noch nicht existiert.

Mach noch ein SaveToFile ans Ende deiner Methoden, dann hast auch gleich sofort den Schreibzugriff mit geprüft.

Und/oder ins SaveToFile zumindestens noch ein ForceDirectory.

KodeZwerg 24. Jul 2022 14:46

AW: ForceFile
 
Zitat:

Zitat von himitsu (Beitrag 1509152)
Man kann sich ja einfach mal den Code des LoadFromFile vornehmen und dort den Dateizugriff anpassen.
In diesem Fall also OPEN_EXISTING durch OPEN_ALWAYS ersetzen und zusätzlich auch den Schreibzugriff zu aktivieren (siehe SaveToFile).
https://docs.microsoft.com/en-us/win...#CREATE_ALWAYS

Delphi-Quellcode:
uses System.RTLConsts;

procedure TForm9.FormCreate(Sender: TObject);
var
  FN: string;
  SL: TStringList;
  FS: {TFileStream}THandleStream;
  FH: THandle;
begin
  FN := ChangeFileExt(Application.ExeName, '.txt');
  SL := TStringList.Create;
  try
    ForceDirectories(ExtractFileDir(FN));
    FH := CreateFile(PChar(FN), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ, nil,
      {OPEN_EXISTING}OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0);
    if FH = INVALID_HANDLE_VALUE then
      //RaiseLastOSError;
      raise EFCreateError.CreateFmt(SFCreateErrorEx, [ExpandFileName(FN), SysErrorMessage(GetLastError)]);
    try
      FS := THandleStream.Create(FH); // hatte der HandleStream nicht mal ein "Owns" und konnte das Handle dann selber freigeben? 
      try
        SL.LoadFromStream(FS);
      finally
        FS.Free;
      end;
    finally
      CloseHandle(FH);
    end;

    //...

    SL.SaveToFile(FN);
  finally
    SL.Free;
  end;
end;
Alternativ alles zufammenfassen und daraus nur eine "Prüfung" bauen.

Delphi-Quellcode:
procedure TForm9.FormCreate(Sender: TObject);
var
  FN: string;
  SL: TStringList;
  FH: THandle;
begin
  FN := ChangeFileExt(Application.ExeName, '.txt');
  SL := TStringList.Create;
  try
    ForceDirectories(ExtractFileDir(FN));
    FH := CreateFile(PChar(FN), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ, nil,
      {OPEN_EXISTING}OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0);
    if FH = INVALID_HANDLE_VALUE then
      //RaiseLastOSError;
      raise EFCreateError.CreateFmt(SFCreateErrorEx, [ExpandFileName(FN), SysErrorMessage(GetLastError)]);
    CloseHandle(FH);

    SL.LoadFromFile(FN);

    //...

    SL.SaveToFile(FN);
  finally
    SL.Free;
  end;
end;


Der FileHandle (FH) und FileStream (FS) ließen sich auch bis zum Ende behalten und direkt zum Schreiben benutzen.
Da kann zwischendrin auch nicht die Datei, bzw. das Schreibrecht und das Sharingrecht verschwieden, weil es die ganze Zeit bestehen bleibt.

Delphi-Quellcode:
procedure TForm9.FormCreate(Sender: TObject);
var
  FN: string;
  SL: TStringList;
  FS: {TFileStream}THandleStream;
  FH: THandle;
begin
  FN := ChangeFileExt(Application.ExeName, '.txt');
  SL := TStringList.Create;
  try
    ForceDirectories(ExtractFileDir(FN));
    FH := CreateFile(PChar(FN), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ, nil,
      {OPEN_EXISTING}OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0);
    if FH = INVALID_HANDLE_VALUE then
      //RaiseLastOSError;
      raise EFCreateError.CreateFmt(SFCreateErrorEx, [ExpandFileName(FN), SysErrorMessage(GetLastError)]);
    try
      FS := THandleStream.Create(FH);
      try
        SL.LoadFromStream(FS);

        //...

        FS.Position := 0;
        FS.Size := 0; // oder nach dem Speichern ein Truncate
        SL.SaveToStream(FS);
        //FS.Truncate; // gibt es nicht, aber Size zuweisen geht ja auch, sowie auch über das Handle
        // also FS.Size := FS.Position;
        // oder SetEndOfFile(FH);
      finally
        FS.Free;
      end;
    finally
      CloseHandle(FH);
    end;
  finally
    SL.Free;
  end;
end;

Du hast seinen Wunsch einer "leeren" Datei vergessen glaube ich. Also eine existierende Datei "leeren".

himitsu 24. Jul 2022 14:50

AW: ForceFile
 
Nein. :angle:

Die Hilfe lesen?
MSDN-Library durchsuchenOPEN_ALWAYS



@Uwe: Schöner wäre es, wenn Die Load/Save ohne Encoding auf die Version mit Encoding gehen würden, anstatt den Stream jeder selber zu erstellen.
So hätte man statt Helper die Klasse unterm selben Namen ableiten und nur zwei Funktion (die mit Encoding) überschreiben müssen.

Am Ende landet ja eh alles bei LoadFromStream/SaveToStream mit Encoding.

Uwe Raabe 24. Jul 2022 16:37

AW: ForceFile
 
Zitat:

Zitat von himitsu (Beitrag 1509159)
@Uwe: Schöner wäre es, wenn Die Load/Save ohne Encoding auf die Version mit Encoding gehen würden, anstatt den Stream jeder selber zu erstellen.
So hätte man statt Helper die Klasse unterm selben Namen ableiten und nur zwei Funktion (die mit Encoding) überschreiben müssen.

:) https://quality.embarcadero.com/browse/RSP-38725

Rollo62 25. Jul 2022 08:12

AW: ForceFile
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1509138)
Mir erschließt sich noch nicht ganz der Sinn ...

Ja, das ist auch mein HauptProblem damit.

Ich könnte mir zwar vorstellen das es da sinnvoll sein könnte wo zwingend Files vorhanden sein sollten, z.B. .ini, .log,
um die Abläufe zu vereinheitlichen bei einfachen Files an denen angehängt werden soll.

Wenn bei Programmstart einmal ForceFile aufgerufen wird, werden diese auf jeden Fall angelegt und nutzbar und man muss sich beim Schreiben nicht mehr drum kümmern.

Trotzdem würde ich auf ein FileExists niemals verzichten und die Frage wäre dann was passieren soll wenn das File doch fehlt (hat irgendwer wie Virenscanner gelöscht).
Dann müsste man das File ja doch wieder an der Stelle neu createn, was ein ForceFile bei Programmstart wieder überflüssig machen würde.

Ein Beispiel wo man ForceFile unbedingt braucht wäre schön :stupid:

KodeZwerg 25. Jul 2022 08:59

AW: ForceFile
 
er spart sich halt beim programm start eine seperate abfrage (könnte theoretisch sofort auf irgend eine art "laden") aber prüft leider kein ergebnis, himitsu sein vorschlag mit einem permanent geöffneten handle plus prüfung finde ich pers. am sinnvollsten für seinen zweck.
(wenn sinn und zweck sein soll sicherzustellen das solange das programm aktiv ist auch diese datei für das programm zur verfügung steht)

Uwe Raabe 25. Jul 2022 10:41

AW: ForceFile
 
Zitat:

Zitat von KodeZwerg (Beitrag 1509185)
er spart sich halt beim programm start eine seperate abfrage

Nicht wirklich. Die Abfrage wird lediglich in ForceFile verlagert - mit einer signifikanten Menge anderem Code. Statt eine FileExists-Abfrage muss nun ein ForceFile gemacht werden, wobei das auch nur für den Moment gilt und beim LoadFromFile schon wieder obsolet sein kann.

Wie schon anderweitig gesagt:
Zitat:

Zitat von Rollo62 (Beitrag 1509181)
Ein Beispiel wo man ForceFile unbedingt braucht wäre schön

Betonung auf unbedingt braucht.

Union 25. Jul 2022 11:03

AW: ForceFile
 
@Monday: Wozu der Weg über eine TStringList? Führst Du Sortierungen durch oder willst die neuesten Sätze zuerst in der Datei haben? Falls nicht, setze doch
Delphi-Quellcode:
TFile.AppendAllText
ein. Die Prozedur besitzt auch einen optionalen Encoding Parameter.

himitsu 25. Jul 2022 11:19

AW: ForceFile
 
Zitat:

Zitat von Union (Beitrag 1509201)
Falls nicht, setze doch
Delphi-Quellcode:
TFile.AppendAllText
ein. Die Prozedur besitzt auch einen optionalen Encoding Parameter.

weil
Zitat:

FreePascal / Lazarus


Aber Notfalls gäbe es auch noch die alten File-API
Delphi-Referenz durchsuchenAppend
oder Delphi-Referenz durchsuchenTStringStream und selber zum Dateiende springen

Rollo62 25. Jul 2022 15:29

AW: ForceFile
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1509199)
Zitat:

Zitat von Rollo62 (Beitrag 1509181)
Ein Beispiel wo man ForceFile unbedingt braucht wäre schön

Betonung auf unbedingt braucht.

Ein Argument was mir dazu einfällt könnte sein dass man bei Programmstart alles in Ruhe vorbereitet, da wo man Zeit übrig hat.

Wärenddessen im Betrieb, da wo man zum Beispiel sehr schnell Events loggen muss, braucht man nicht mehr (oder nur im Notfall) beim Ersten Log erst noch etwas länger das File erzeugen.
So kämen alle Logs auf ähnliches Timing und nicht der Erste etwas verzögert.
Das wäre also ein reines Timing-Argument, allerdings doch eher schwach bei den heutigen PC's ...
Wer solche Timingprobleme hat macht das sowieso anders.

himitsu 25. Jul 2022 18:07

AW: ForceFile
 
Aber gerade dann wäre sowas gefährtlich. (abgesehn von der Variante die ganze Zeit über das Handle aktiv zu halten)

Du prüfst nur beim Start und dann kommt wer auf die Idee mitten drin die Datei/Verzeichnis zu löschen
und peng.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:04 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 by Thomas Breitkreuz