Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   TFileStream Fehler (https://www.delphipraxis.net/204251-tfilestream-fehler.html)

tomkupitz 11. Mai 2020 11:50

TFileStream Fehler
 
Hallo,

ich benutze TFileStream um meine Projektdaten (fortfolgend Integer-, Extended-Werte etc.) auf die Platte zu speichern. Dazu benutze ich Read und Write. Im Feld kommt es nun in seltenen Fällen dazu, dass Dateien beschädigt sind. Das kann ich anhand von Prüfsummen gut erkennen.

Meine allgemeine Frage ist nun: Habt ihr ähnliche Erfahrungen mit TFileStream und welche Ursachen gibt es dafür (Virenscanner o.ä.)?

Danke und beste Grüße

hoika 11. Mai 2020 11:59

AW: TFileStream Fehler
 
Hallo,
wie groß sind die denn Dateien?

Je größer, desto mehr könnte eine Virenscanner was mit zu tun haben.

Arbeitest Du mit mehreren Threads?

tomkupitz 11. Mai 2020 12:10

AW: TFileStream Fehler
 
das Speichern passiert ohne weitere Threads. Die Dateien sind bis max. 10MB groß.

Beste Grüße

scrat1979 11. Mai 2020 12:39

AW: TFileStream Fehler
 
Ich arbeite sehr viel mit TFileStream, unter anderem um Konfigurationen zu speichern. Korrupte Dateien sind mir diesbezüglich noch nicht untergekommen.

Was bei mir immer wieder zu Fehlern führte waren „fehlerhafte“ Speicherungen welche nicht „kompatibel“ mit den jeweiligen Typen beim Einlesen waren. Da lag der Fehler dann aber VOR dem Monitor...

Gausi 11. Mai 2020 12:43

AW: TFileStream Fehler
 
Sind denn Probleme mit der Hardware ausgeschlossen?

himitsu 11. Mai 2020 13:07

AW: TFileStream Fehler
 
VirenScanner sollten doch keine Teile in Dateien ohne Rückmeldung ändern?

Ansonsten macht TFileStream nicht Schlimmes und reicht dein Zeug direkt an Windows weiter (MSDN-Library durchsuchenWriteFile). Es hat auch keinen eigenen Cache, so wie z.B. die alten PascalFunktionen um Delphi-Referenz durchsuchenAssignFile, wo dann was verschwienden könnte, wenn du nicht richtig schließt.


ABER so wie früher gibt es auch hier zwei Funktionen zum Schreiben und auch nochmal zum Lesen.
Write und BlockWrite, bzw. jetzt ebenfalls .Write und .WriteBuffer, wobei jeweils Letzeres den Erfolg prüft, außer du willst selber Prüfen, aber dann solltest du auch das Result vom Write behandeln.
z.B. Platte ist voll, oder sonstige Fehler beim Schreiben (z.B. auch wenn der Virenscanner das Schreiben verbietet)


PS: Es gibt auch TReader und TWriter. Ddie Dinger werden z.B. von der VCL/FMX verwendet, um die BinärVersion der DFM zu speichern.
Sie speichern zu jedem Wert auch das Format, validieren beim Lesen die Typen und so kann man auch eine "Zahl" lesen, egal ob es Byte, Word oder Integer ist, oder String als ANSI oder UTF-8.

tomkupitz 11. Mai 2020 13:15

AW: TFileStream Fehler
 
der Fehler tritt wirklich selten auf (bei uns in der Applikation nie). Doch gerade bei unseren OEMs stößt das sauer auf...

Hardwareprobleme kann ich auch nicht ausschließen.

Beste Grüße

hoika 11. Mai 2020 13:25

AW: TFileStream Fehler
 
Hallo,
Zitat:

VirenScanner sollten doch keine Teile in Dateien ohne Rückmeldung ändern?
Es reicht ja, das Schreiben ein kleines bissel zu "verlangsamen".
Und wenn die Software dann das Schreiben abbricht -> Dateifehler.

Abhilfe könnte sein, die Datei unter einem anderen Namen zu speichern,
und wenn das geklappt hat (Prüfsumme), die Datei umzubenennen in den richtigen Dateinamen.

himitsu 11. Mai 2020 13:55

AW: TFileStream Fehler
 
Zitat:

Zitat von hoika (Beitrag 1464264)
Es reicht ja, das Schreiben ein kleines bissel zu "verlangsamen".
Und wenn die Software dann das Schreiben abbricht -> Dateifehler.


Eigentlich nicht.
Du gehst hier über den FileCache des OS, außerdem wartet dein Programm auf das Ende der Schreiboperation (Write/Close), da hier keine overlapped/asynchrone API benutzt wird.
Wenn es einen Fehler gibt und die Rückgabewerte ausgewertet werden, dann gibt es eine Fehlermeldung/Exception, falls z.B. der Virenscanner oder ein defektes Laufwerk sich meldet.
Und ist das Write zurückgekommen, dann steht es im WindowsFileCache ... selbst wenn du dann schnell das Programm abschießst, so lange du nicht auch Windows hart beendest, wird immernoch gespeichert ... kommt es da nochmal zu einem Fehler, dann poppt ein Popup auf und Windows meldet sich. (eigene Erfahrung, mit defekter USB-Platte, bzw. bei Fehlbedinung)

Es gab nur einen Fall, wo ich jahrelang Datenfehler hatte, aber da war es ein defekter USB 3-Treiber für meinen Intel-Chipsatz, der auf USB-Platten und bei USB-LAN-Adaptern alle paar MB immer mal paar Byte falsch übertagen hat und das nicht merkte.
Oder natürlich die Schuld des Benutzers ... Festplatte/USBStick abziehen, bevor fertig gespeichert wurde.

dummzeuch 11. Mai 2020 14:59

AW: TFileStream Fehler
 
Benutzt Du .Write oder .WriteBuffer?

Falls ersteres: Prüfst Du auch den Rückgabewert, ob der komplette Buffer geschrieben wurde? Wenn nein, dürfte das das erste Problem sein.

Wir benutzen TFileStream in sehr großem Umfang und das auch noch multithreaded. Da geht normalerweise nichts verloren.

Aber wenn man nicht prüft, ob auch alles geschrieben wurde.

tomkupitz 11. Mai 2020 15:31

AW: TFileStream Fehler
 
nutze nur Write und prüfe auch die Rückgabe. Stimmt soweit alles. Bleibt also der "externe Einfluss" auf das File nach dem Schreiben.

Delphi.Narium 11. Mai 2020 16:14

AW: TFileStream Fehler
 
Hab' sowas mal erlebt vor einigen Jahren:

Client schreibt per TaskPlaner konfiguriert alle 20 Minuten eine Datei in ein Verzeichnis auf einen Server.

Server liest per TaskPlaner alle 30 Minuten diese Verzeichnis aus, verarbeitet die dort gefundenen Dateien und verschiebt sie dann in ein Archiv.

Dabei konnte es passieren, dass der Server eine Datei liest, verarbeitet und verschiebt, während der Client sie noch schreibt.

Das kann auf Dauer nicht gut gehen und führt halt sporadisch zu Fehlern.

(Achso: Die Entwickler der beiden Programme hatten sie so geschrieben, dass sie Fehler großzügig ignorierten :-()

Eventuell eine ähnliche Konstellation beim Kunden?

Oder, sofern die Dateien ins "Netz" geschrieben werden sollten: Eventuell eine etwas "hakelige" Netzverbindung, die sporadisch mal (kurzfristig) unterbrochen wird?

Was steht bei Dir im Create des TFileStream für Mode?

Eventuell mal mit den möglichen Kombinationen "rumexperimentieren".

z. B.:
Delphi-Quellcode:
tFileStream('dateiname',fmCreate or fmShareExclusive);

tomkupitz 11. Mai 2020 17:43

AW: TFileStream Fehler
 
ich habe manchmal nur fmCreate verwendet. Dann ist

Zitat:

tFileStream('dateiname',fmCreate or fmShareExclusive);
ein Ansatz. Danke.

himitsu 11. Mai 2020 18:24

AW: TFileStream Fehler
 
Ja, Delphi ist hier bissl Andersrum.

Eigentlich ist beim MSDN-Library durchsuchenCreateFile standardmäßig alles Exclusiv, aber beim TFileStream standardmäßig alles Shared.


Allerdings hast du beim fmCreate ein kleines Problem, denn dort kann man die Shared-Attribute nicht benutzen, weil das bereits $FFFF ist und $0010 (fmShareExclusive) da nicht mehr rein passt.
Falls nichts hilft, dann wäre noch
Delphi-Quellcode:
THandleStream.Create(CreateFile(...), True)
eine Variante.



PS: TFile.CreateXYZ, .OpenXYZ, .WriteXYZ und .AppendXYZ gibt es auch noch, auch wenn das intern auch wieder TFileStream benutzt, aber wenn es eh keinen Unterschied macht, dann wenigstens "einfach". :stupid:
Delphi-Referenz durchsuchenIOUtils.TFile

samso 12. Mai 2020 06:23

AW: TFileStream Fehler
 
Zitat:

Zitat von himitsu (Beitrag 1464299)

Allerdings hast du beim fmCreate ein kleines Problem, denn dort kann man die Shared-Attribute nicht benutzen, weil das bereits $FFFF ist

Das ist schon seit vielen Jahren nicht mehr so (mindestens seit Delphi 2010):

Delphi-Quellcode:
unit Classes;
...
const
{ TFileStream create mode }

  fmCreate = $FF00;
Das ändert aber nichts daran, dass ein simples
Delphi-Quellcode:
TFilestream.Create(Filename, fmCreate)
die Datei immer mit exclusivem Zugriff erstellt.
Erst wenn man den Share-Mode explizit angibt wird dieser benutzt. Damit ist es möglich die Datei mit "fmCreate or fmShareDenyWrite" zu erstellen um so anderen Programmen die Möglichkeit zu geben die Datei bereits während des Schreibens zu lesen (z.B. bei Logdateien). Diese Möglichkeit gab es bei den sehr alten Delphiversionen (z.B. Delphi 2007) so nicht.

himitsu 12. Mai 2020 10:51

AW: TFileStream Fehler
 
Ohh, dann hatten se das unbemerkt irgendwann behoben. :thumb: (im XE war es noch $FFFF, wo ich gestern nur mal schnell in den Code schaute :oops:)

Wer hätte den ahnen können, dass es nach 20 Jahren mal repariert wird. :stupid:

samso 12. Mai 2020 12:23

AW: TFileStream Fehler
 
Zitat:

Zitat von himitsu (Beitrag 1464350)
(im XE war es noch $FFFF, wo ich gestern nur mal schnell in den Code schaute :oops:)

Sorry, aber das glaube ich nicht, denn in der offiziellen Dokumentation steht etwas anderes VCL/XE/en/Classes

himitsu 12. Mai 2020 14:12

AW: TFileStream Fehler
 
Als wenn jemals in der Hilfe immer die Wahrheit drin stand. :angle2:

Ich war mir ganz sicher gestern noch ein
Delphi-Quellcode:
const
  fmCreate = $FFFF;
gesehn zu haben, als ich nach fmShareExclusive suchte.

Hmmm, stimmt, du hast Recht.

Aber fand grade nur noch diese Stelle (vermutlich diese Stelle im Augenwinkel gehabt)
Delphi-Quellcode:
constructor TFileStream.Create(const AFileName: string; Mode: Word; Rights: Cardinal);
var
  LShareMode: Word;
begin
  if (Mode and fmCreate = fmCreate) then
  begin
    LShareMode := Mode and $FF;
    if LShareMode = $FF then
      LShareMode := fmShareExclusive; // For compat in case $FFFF passed as Mode
und dich denke nicht, dass mir die Reste der alten Delphi 4, 7, TurboPascal und FreePascal unter die Augen kamen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:30 Uhr.

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