Dateien schreiben - Returncode

Für allgemeine Fragen zur Programmierung mit PureBasic.
Andreas
ToolbarKönig
Beiträge: 142
Registriert: 08.09.2004 08:33

Beitrag von Andreas »

Prowokant hat geschrieben:Das Problem ist gelöst!
Dann klappts auch wieder mit der Nachbarin.
Nach FlushFileBuffers(1) kannst Du auf den letzen angefallenen Fehler testen.
Hier ein kleines Beispiel, damit bekommst Du auch gleich die passende Fehlermeldung angezeigt. Aber Vorsicht mit der Nachbarin, siehe 2. Meldung

Code: Alles auswählen

Procedure ShowLastError(Error)
Error$ = Space(255)
If Error
   FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM,0,Error,0,Error$,Len(Error$),0)
   MessageRequester("Fehler #"+Str(Error)+"#",Error$,0)
EndIf
EndProcedure

SetLastError_(#ERROR_DISK_FULL);Fehler-Code simulieren
ShowLastError(GetLastError_())

SetLastError_($0FA6);Alles klar ???
ShowLastError(GetLastError_())
Gruss Andreas
Prowokant
Beiträge: 34
Registriert: 11.05.2006 13:46
Wohnort: Münster

Beitrag von Prowokant »

@ Andreas

Danke.
Ich muss mich wohl doch noch mehr mit den Windows
Funktionalitäten rumquälen. Wenn man vernünftig mit
PureBasic programmieren will, kommt man wohl (leider)
nicht drum herum. Schade, denn ich finde MSDN nicht
sehr selbsterklärend. Ich suche mir da immer 'n Wolf.
Ich gehe aber mal davon aus, dass es ergänzend so
20, 30 Funktionen sind, mit denen man auskommt. PB
selbst ist ja ganz gut bestückt. Hat da schon jemand
was Wiki-mäßiges zusammengeschrieben?

> SetLastError_($0FA6)

Nett.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Bevor man schreibt prüfen ob genug Platz. Am ende testen ob alles
geschreiben. (Also die gesamte Datei)

Das schreiben auf Disketten sollte bei den meisten wohl die seltene
Ausnahme sein. Alle Geschwindigkeitszuwächse durch Buffering sind durch
diese FlushFileBuffers wieder verloren, wird also nur sehr selten Sinn machen
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Prowokant
Beiträge: 34
Registriert: 11.05.2006 13:46
Wohnort: Münster

Beitrag von Prowokant »

@ ts-soft

>Bevor man schreibt prüfen ob genug Platz.

Wenn man die zu erwartende Dateigröße vorab kennt, ist das eine
Möglichkeit, um die Warscheinlichkeit des Auftretens eines der in
Frage kommenden Fehler zu reduzieren. Nicht mehr. Du musst
bei der Programmierung immer von einem Multiuser/Multitasking-OS
ausgehen.

> Am ende testen ob alles geschreiben. (Also die gesamte Datei)

Das würde bedeuten, dass du jedes geschriebene Byte zählen
musst. Das darf bei einer aktuellen Programmiersprache nicht
nötig sein. Das kostet zu viel Zeit. Es ist einfach nicht praktikabel.
Es gibt immer Wege, ein Problem zu umgehen. Letztlich kannst
du mit PB ja Assemblercode einarbeiten. Das darf aber für solch
elementare Dinge, wie das Schreiben einer Datei nicht nötig sein.

> Das schreiben auf Disketten sollte bei den meisten wohl die
> seltene Ausnahme sein.

Das Schreiben auf Diskette war für mich eine probate Möglichkeit
einen der gängigen Fehler zu provozieren. Es gibt viele Fehler
beim Schreiben, die dir zeitgemäßer erscheinen mögen. Lass
mich hier noch einmal das Herausziehen des USB-Sticks
während des Schreibens nennen. Zudem werden auch Festplatten
voll; vielleicht arbeitet jemand unter Disk Quota bzw. User Quota
und und und

> Alle Geschwindigkeitszuwächse durch Buffering sind durch
> diese FlushFileBuffers wieder verloren

Ja, das ist leider der Fall. Das liegt aber nicht an der Tatsache, dass
man sinnvollerweise so programmieren sollte, wie es in diesem
Thread beschrieben wird. Das Problem ist, dass das Schreiben per
"Write..." immer die Anzahl der geschriebenen Zeichen liefert. Die
Zeichen werden gepuffert und irgendwann wird der Puffer
geschrieben. Erst zu diesem Zeitpunkt können viele Probleme
auftreten. Der "Write..." liefert aber trotzdem weiterhin die besagte
Anzahl. Würde er nach einem Fehler beim Schreiben des Puffers
z.B. eine negative Anzahl von Zeichen liefern, so könnte ein
Programm rechtzeitig reagieren. So, wie der "Write..." derzeit
implementiert ist, kann man IMHO nicht anders handeln, als hier
beschrieben. Das Risiko, einfach nur Mist auf die Platte zu schreiben,
ist zu hoch.

> wird also nur sehr selten Sinn machen

Wenn du mit dem Risiko leben magst...
Meine Erfahrung sagt mir, dass man das keinesfalls machen kann.
Wenn irgendwo Fehler auftreten, dann beim Schreiben auf die
Platte. Was nützt es, wenn man Daten schneller auf die Platte
bringen kann, aber nicht sicher sein kann, ob auch wirklich das auf
der Platte steht, was man erwartet? Das Wichtigste ist doch die
Integrität der Daten. ... wird also immer Sinn machen!
Benutzeravatar
bobobo
jaAdmin
Beiträge: 3873
Registriert: 13.09.2004 17:48
Kontaktdaten:

Beitrag von bobobo »

Prowokant hat geschrieben: Das würde bedeuten, dass du jedes geschriebene Byte zählen
musst. Das darf bei einer aktuellen Programmiersprache nicht
nötig sein.
nochmal langsam ?

WriteStringn() liefert Dir als Rückgabe die Anzahl der geschriebenen
Bytes (Getestet hier unter unmöglichen Bedingungen Windoof XP,
kein Diskettenlaufwerk, stattdessen ein per crosscrypt emuliertes
fast volles aber gleichzeitig komprimiertes (bringt nette schwankende
Zahlen beim Writestring() weil die Komprimierung etwas braucht) volles
Laufwerk)
‮pb aktuel 6.2 windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
Prowokant
Beiträge: 34
Registriert: 11.05.2006 13:46
Wohnort: Münster

Beitrag von Prowokant »

@ bobobo

> WriteStringn() liefert Dir als Rückgabe die Anzahl der geschriebenen
> Bytes

WriteStringN liefert Dir als Rückgabe die Anzahl der gepufferten Bytes.
Die Anzahl der geschriebenen Bytes liefert FlushFileBuffers. Nur wenn
diese beiden Rückgabewerte identisch sind, dann hat das Schreiben
bis zur Platte tatsächlich geklappt und du darfst darauf vertrauen, dass
das was du schreiben wolltest auch das ist, was du geschrieben hast.
Benutzeravatar
bobobo
jaAdmin
Beiträge: 3873
Registriert: 13.09.2004 17:48
Kontaktdaten:

Beitrag von bobobo »

aha

Mach den Puffer aus und es passt wieder :)

Oder benutz DOS (ohne smartdrv) :mrgreen:

Ansonsten musst Du so ne es halt per flushing nebst errorcheck lösen.

Mir hat jedenfalls die Rückgabe von Writestringn() im Test ausgereicht.

Kommunizieren tut man doch eh letztlich immer nur per
Treiber/System-API und nicht (mehr) direkt mit der Hardware.

Das Problem stellt sich doch wohl eh nur bei Arbeiten mit entnehmbaren
Datenträgern und dort auch nur wenn man zu blöd ist sich nicht an
den empfohlenen Umgang damit zu halten. Da kann man dann auch
etwas Aufwand (mehr Geld) in DAUsichere Softwareentwicklung stecken.
‮pb aktuel 6.2 windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
Prowokant
Beiträge: 34
Registriert: 11.05.2006 13:46
Wohnort: Münster

Beitrag von Prowokant »

@ bobobo

> Mach den Puffer aus und es passt wieder :)

Hast du ein Codefragment, mit dem man das machen kann?

> Oder benutz DOS (ohne smartdrv)

Danke. Lieber nicht.

> Mir hat jedenfalls die Rückgabe von Writestringn() im Test
> ausgereicht.

Was macht dein Testprogramm, um das zu erreichen?

> Kommunizieren tut man doch eh letztlich immer nur per
> Treiber/System-API und nicht (mehr) direkt mit der Hardware.

Ja, klar. Und?!

> Das Problem stellt sich doch wohl eh nur bei Arbeiten mit
> entnehmbaren Datenträgern

Es gibt genug Probleme, die auch mit Festplatten bestehen.

> und dort auch nur wenn man zu blöd ist sich nicht an den
> empfohlenen Umgang damit zu halten.

Das stimmt so einfach nicht. Du machst es dir zu einfach.

> Da kann man dann auch etwas Aufwand (mehr Geld) in
> DAUsichere Softwareentwicklung stecken.

Den Aufwand sollte jeder, der halbwegs brauchbare Programme
schreibt, immer treiben. Aber du scheinst das Problem ja sehr
elegant gelöst zu haben. Verrate mir doch bitte, wie dein Programm
den Puffer ausschaltet bzw. was ich tun muss, damit WriteStringN
Rückgabewerte liefert, die brauchbar sind. Wenn das irgendwie
geht, dann wäre das sicherlich die beste Lösung.

Ansonsten scheint das Thema durch zu sein. Es bringt nichts
und ich habe auch keine Lust noch weiter zu erklären, dass
die Prüfung von Schreiboperationen unabdingbar ist. Man kann
über einen Weg diskutieren, wie man mit der mangelhaften
Funktionalität von PB an dieser Stelle zurecht kommt, aber es
macht keinen Sinn, die Notwendigkeit anzuzweifeln. Wenn mir
jemand einen Fehler in meinem Programm zeigt, der das korrekte
Verhalten von PB vereitelt, dann bin ich dankbar und wenn ich
einen eleganten Weg gezeigt bekomme, das Problem zu lösen,
so bin ich ebenfalls dankbar. Zu versuchen, mir zu erklären, dass
man das gar nicht braucht jedoch ist, mit Verlaub, Schwachsinn.
Es tut mir leid, aber ich habe keine Lust auf Kindergarten.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Prowokant, ich stimme dir zu; ich finde auch, dass ein paar mehr Befehl ReturnCodes haben können, ob ihre Operationen erfolgreich waren, beispielsweise SetClipboardText() oder PauseThread().
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Prowokant hat geschrieben: > Mach den Puffer aus und es passt wieder :)

Hast du ein Codefragment, mit dem man das machen kann?

Code: Alles auswählen

FileBuffersSize(#Datei, 0)
Eine Datei ist normallerweise erst bei CloseFile geschrieben und wird auch
erst dann geprüft. Ob ich jede Zeile teste oder am Ende feststelle, es hat
nicht geklappt, und ich mache Meldung beim User, da ist der normalle Weg,
am Ende testen, ein vielfaches schneller und IMHO genauso sicher.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Antworten