Hallo, ich schreibe gerade ein Skript, das basierend auf der Usereingabe mehrere hundert Zeilen in eine Textdatei schreiben wird. Für jede Zeile ist eine Usereingabe notwendig.
Es wäre also sehr blöd, wenn das Skript aus welchem Grund auch immer, an irgendeiner Stelle irgendeinen Fehler bekommt, der PC abstürzt, oder dergleichen - und der ganze Fortschritt weg wäre.
Wie würdet ihr vorgehen, um nach jedem Eintrag den Fortschritt zu sichern, sodass es praktisch ausgeschlossen ist, dass so ein Fall einreten kann? Sind die write-Operationen schon von Haus aus robust genug oder reicht es bereits, die Datei nach jedem Eintrag neu zu öffnen und zu schließen?
Textdatei 'sicher' beschreiben
- CrisBee
- User
- Beiträge: 61
- Registriert: Mittwoch 2. Oktober 2013, 10:45
- Wohnort: Bielefeld
- Kontaktdaten:
Wenn mich nicht alles täuscht, dann kannst du die Textdatei im Append Mode öffnen 'a+', damit wird der String immer hinten angehängt. Das Ganze realisierst du in einer Schleife, so dass nach jeder Eintragung die Datei wieder geschlossen wird.
Aber ich bin selber Neuling, also vielleicht hat ein User mit mehr Erfahrung einen besseren Vorschlag.
Aber ich bin selber Neuling, also vielleicht hat ein User mit mehr Erfahrung einen besseren Vorschlag.
Das Reallife ist nur etwas für Leute, die keine Freunde im Internet haben!
Meine Fotografie: http://www.cutefeet.de
Meine Fotografie: http://www.cutefeet.de
@Karl: Das reicht nicht, weil das Betriebssystem trotzdem erst einmal alles im RAM zwischenspeichern kann. Schau Dir mal `os.fdatasync()` an. Das mit schliessen und öffnen der Datei zwischen jedem Schreibvorgang macht keinen Sinn.
- CrisBee
- User
- Beiträge: 61
- Registriert: Mittwoch 2. Oktober 2013, 10:45
- Wohnort: Bielefeld
- Kontaktdaten:
Danke BlackJack!
Das Reallife ist nur etwas für Leute, die keine Freunde im Internet haben!
Meine Fotografie: http://www.cutefeet.de
Meine Fotografie: http://www.cutefeet.de
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Aus Usabilitysicht hört sich das aber auch alles andere als toll an... wenn ich mehrere Hundert Eingaben mache, dann will ich das doch beliebig unterbrechen können‽
Letztlich stelle ich mir das vor, wie bei jedem anderen Programm auch, mit welchem man umfangreiche Eingaben macht. Sei es nun ein Texteditor oder ein CAD Programm oder sonst was. Der Benutzer muss eben ab und an speichern bzw. das Programm sichert alle paar Minuten mal Arbeit weg. Ansonsten ist eben die Arbeit von zwischendurch verloren.
Abstürze usw. sind ja schön und gut, aber was ist denn mit dieser imho Standard Anforderung?
Letztlich stelle ich mir das vor, wie bei jedem anderen Programm auch, mit welchem man umfangreiche Eingaben macht. Sei es nun ein Texteditor oder ein CAD Programm oder sonst was. Der Benutzer muss eben ab und an speichern bzw. das Programm sichert alle paar Minuten mal Arbeit weg. Ansonsten ist eben die Arbeit von zwischendurch verloren.
Abstürze usw. sind ja schön und gut, aber was ist denn mit dieser imho Standard Anforderung?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Es klingt auch ein wenig paranoid, denn kein normales Programm macht das. Texteditoren, Tabellenkalkulationen, CAD-Programme usw. speichern alle einfach nur, ohne sich speziell darum zu kümmern ob die Daten nun wirklich *sofort* auf dem Hintergrundspeicher ankommen. So ein erzwungenes Syncen bremst nämlich auch das System aus. Wann was wohin gespeichert wird, kann das Betriebssystem auf einem Mehrprozess-System nämlich in der Regel effizienter koordinieren als einzelne Anwendungsentwickler. Explizites Syncen beschränkt sich in der Regel auf so etwas wie systemrelevante Logdateien wo man nach einem Absturz die kurz vor dem Absturz geschriebenen Daten brauchen kann um die Ursache für den Absturz zu analysieren.
Äh, deshalb will ich ja gerade, dass nach jedem Eintrag gespeichert wird, was genau meine Frage ist? Unterbrechen können soll man das jederzeit entweder per Script schließen, oder eine entsprechende Konsoleneingabe.Aus Usabilitysicht hört sich das aber auch alles andere als toll an... wenn ich mehrere Hundert Eingaben mache, dann will ich das doch beliebig unterbrechen können‽
Da ich das Programm erst mal sowieso nur für meine privaten Zwecke nutze, muss es nicht allzu viel Usability haben, sondern vorranging das tun, was ich will.
@BlackJack: Performance sollte wirklich kein Problem sein, wenn man alle paar Sekunden eine Zeile in eine Textdatei schreibt. Ich glaube ich könnte die Datei zwischendurch millionenfach öffnen und schließen.
Wenn die Quintessenz jetzt aber ist, dass normales Beschreiben (also file.write()) auch reicht, bin ich damit auch zufrieden. Wollte nur unangenehmen Überraschungen vorbeugen
@Karl: Doch Performance ist ein Problem beim erzwungenen Syncen, was auch nichts mit öffnen und schliessen von Dateien zu tun hat. Ständiges öffnen und schliessen hat nur einen Effekt auf das Programm welches das tut. Mit einem Sync bremst man andere Programme im Plattenzugriff aus und blockiert das Programm das den Sync angefordert hat solange bis der durch ist. Das Betriebssystem regelt das besser als Anwendungsprogrammierer die denken ihr Programm wäre das wichtigste und braucht unbedingt Vorfahrt, weil das Betriebssystem einen Überblick über alle anstehenden Lese- und Schreibvorgänge hat, und die versucht in einer möglichst günstigen Reihenfolge abzuarbeiten, so dass das Gesamtssystem flüssig läuft.
Ein Absturz wenn man gerade mitten am arbeiten ist, ist immer eine unangenehme Überraschung, aber doch auch äusserst selten. Falls das nicht selten ist, sollte man die Ursache finden und beseitigen, und nicht einzelne Programme ”sicherer” machen. Da hat man mehr von.
Ein Absturz wenn man gerade mitten am arbeiten ist, ist immer eine unangenehme Überraschung, aber doch auch äusserst selten. Falls das nicht selten ist, sollte man die Ursache finden und beseitigen, und nicht einzelne Programme ”sicherer” machen. Da hat man mehr von.
Deine ideologischen Vorstellungen haben durchaus ihre Berechtigung und grundsätzlich stimme ich dir auch vollkommen zu.
Aber hier handelt es sich wirklich um en Szenario, in dem selbst mein Taschenrechner noch unterfordert wäre, also denke ich, dass man das nicht so eng sehen muss. Aber streiten wir uns nicht, für mich ist die Sache jetzt klar, danke
Aber hier handelt es sich wirklich um en Szenario, in dem selbst mein Taschenrechner noch unterfordert wäre, also denke ich, dass man das nicht so eng sehen muss. Aber streiten wir uns nicht, für mich ist die Sache jetzt klar, danke
@Karl: Ich weiss jetzt nicht was Du mit „idiologisch” meinst!? Das Betriebssystem hat den Überblick über die anstehenden Lese- und Schreiboperationen und wo die auf der Platte stattfinden, und welche Programme am längsten schon keine Daten mehr bekommen haben oder losgeworden sind, und versucht die alle möglichst effizient zu bedienen. Datentransfer von und zur Platte und unnötige Kopfbewegungen dauern Grössenordnungen länger als Datentransfers zwischen Prozessor und RAM und Verarbeitung der Daten in der CPU. Und da pfuscht ein Sync dazwischen und zwar anscheinend in Deinem Fall regelmässig. Und dem gegenüber steht ein ”Gewinn” der fast 0 ist. Das ist einfach unsinnig. Wenn das mehr Leute für nicht so schlimm halten würden und so etwas in ihre Programme einbauen, zwingt das auch sehr leistungsstarke Rechner in die Knie.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Und wieso muss dann nach *jedem* Eintrag gespeichert werden? Wenn man die Eingabe nach dem Speichern an einer *beliebigen* Stelle wieder aufnehmen kann, braucht es doch so etwas nicht‽Karl hat geschrieben:Äh, deshalb will ich ja gerade, dass nach jedem Eintrag gespeichert wird, was genau meine Frage ist?Aus Usabilitysicht hört sich das aber auch alles andere als toll an... wenn ich mehrere Hundert Eingaben mache, dann will ich das doch beliebig unterbrechen können‽
In meinem Texteditor kann ich nach jeder Zeile speichern oder eben erst nach 10 oder gar 20 Zeilen oder zum Teufel auch erst, wenn ich 1000 Zeilen Code geschrieben habe. Da bleibt es mir als Anwender überlassen, wie viele Änderungen ich am Stück mache. Wer aufgrund eines Absturzes viele Stunden Arbeit verliert, der wird in Zukunft eben häufiger speichern - aber sicherlich nicht nach jeder Zeile / Eintrag.
Also dieses Szenario würd ich ja doch gerne mal kennen lernen, was das rechtfertigt. Zumal es sich um die Einträge in eine Textdatei handelt Dafür sind die Dinger imho nicht ausgelegt. Bei solch einer Anforderung müsstest Du die Einträge imho an irgend einen Dienst schicken, der die verwaltet, etwa eine Datenbank in jedweder Form o.ä.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Erst mal will ich noch mal betonen, dass es sich um ein Skript handelt, das für mich persönlich etwas erledigen soll.
Was es macht, ist nach einer Usereingabe eine Zeile in eine Textdatei zu schreiben. Das wird dann alle paar Sekunden gemacht, je nachdem wie schnell ich bin.
Meine Frage bezog sich ursprünglich nur darauf, ob ich zusätzliche Maßnahmen ergreifen sollte, um das Datei-schreiben abzusichern. Ich könnte durchaus mal eine Stunde lang tippen und wenn dann alles weg wäre, wäre das sehr ärgerlich.
Mir ist durchaus bewusst, wie der Computer in seinen Grundzügen arbeitet und wie das Betriebssystem die Prozesse verwaltet. Aber die ganz spezielle Frage, ob ich bei file.write() Vorkehrungen treffen sollte, um den Fortschritt zu speichern, war/ist mir nicht ganz klar, weil ich schlicht und einfach nicht exakt weiß, wie diese Methode und das Betriebssystem usw sich verhalten.
@Hyperion: Schön, dass du so einen tollen Texteditor hast, aber der hat sicherlich mehr als 50-100 Zeilen und eine Entstehungsgeschichte von mehr als 20 Minuten, oder?
Das hier ist ein simples "Quick'n Dirty" Skript, welches mir in meinem Alltag grad mal etwas erleichtern soll. Es soll auch nicht noch irgendwelche generischen Aufgaben erfüllen, oder Schnittstellen für Erweiterungen und ein gutes OO-Design haben. Es soll einfach das machen, was ich will, und zwar genau das und nichts anderes. Und das ist nicht gerade sehr viel.
Ich will nicht falsch verstanden werden: Ich finde dieses Forum sehr toll und auch gerade die tollen und oft hilfreichen Beiträge von Blackjack sind immer sehr beliebt bei mir, wenn ich mal im Forum stöbere.
Aber irgendwie ist jetzt aus einer Mücke ein Elefant geworden. Ich will einfach, dass mein Skript tut und möglichst auch - für welchen Fall auch immer - die Daten nicht verliert.
Da mein Skript eine Textdatei beschreiben soll, lag es mir jetzt nahe, lieber dort eine - vielleicht unschöne - Lösung zu suchen, als mir jetzt noch Gedanken über irgendwelche Dienste/Datenbanken zu machen.
Ob und wie viele unnötige CPU-Zyklen und Speicherzugriffe ich mir damit einhandle, ist da doch vollkommen egal. Aber hier werde ich irgendwie direkt für den Vorschlag verteufelt, ein paar unnötige Festplattenzugriffe zu verursachen (auf meinem System, auf dem eh nichts passiert).
Wenn ich jemals für ein breiteres Publikum als mich selbst entwicklen sollte, dann würde ich jedem eurer Worte bedingungslos zustimmen. Wenn ich etwas entwickle, das auch gleichzeitig Spaß beim Programmieren machen soll, würde ich auch nie so programmieren.
Ich hoffe, ihr nehmt mir diese gottlosen Blasphemien nicht zu sehr übel
Was es macht, ist nach einer Usereingabe eine Zeile in eine Textdatei zu schreiben. Das wird dann alle paar Sekunden gemacht, je nachdem wie schnell ich bin.
Meine Frage bezog sich ursprünglich nur darauf, ob ich zusätzliche Maßnahmen ergreifen sollte, um das Datei-schreiben abzusichern. Ich könnte durchaus mal eine Stunde lang tippen und wenn dann alles weg wäre, wäre das sehr ärgerlich.
Mir ist durchaus bewusst, wie der Computer in seinen Grundzügen arbeitet und wie das Betriebssystem die Prozesse verwaltet. Aber die ganz spezielle Frage, ob ich bei file.write() Vorkehrungen treffen sollte, um den Fortschritt zu speichern, war/ist mir nicht ganz klar, weil ich schlicht und einfach nicht exakt weiß, wie diese Methode und das Betriebssystem usw sich verhalten.
Damit meine ich, dass deine Ansichten das wiederspiegeln, was man bei einem guten Design machen sollte. Ideologisch, weil es zwar gut und richtig so ist, aber nicht in jedem Fall dem praktisch gegangenem Weg entsprechen dürfte.BlackJack hat geschrieben:ch weiss jetzt nicht was Du mit „idiologisch” meinst!?
Natürlich, ist ja auch klar. Aber gucken wie uns doch mal die Verhältnismäßigkeit an: SSD, moderne CPU, PC macht sowieso nicht viel, wenn ich dieses Skript benutze - Performance? Mir doch egal, von mir aus kann das Ding zwischen meinen Usereingaben noch ein paar Graphenisomorphien nachrechnen.BlackJack hat geschrieben:Wenn das mehr Leute für nicht so schlimm halten würden und so etwas in ihre Programme einbauen, zwingt das auch sehr leistungsstarke Rechner in die Knie.
@Hyperion: Schön, dass du so einen tollen Texteditor hast, aber der hat sicherlich mehr als 50-100 Zeilen und eine Entstehungsgeschichte von mehr als 20 Minuten, oder?
Das hier ist ein simples "Quick'n Dirty" Skript, welches mir in meinem Alltag grad mal etwas erleichtern soll. Es soll auch nicht noch irgendwelche generischen Aufgaben erfüllen, oder Schnittstellen für Erweiterungen und ein gutes OO-Design haben. Es soll einfach das machen, was ich will, und zwar genau das und nichts anderes. Und das ist nicht gerade sehr viel.
Ich will nicht falsch verstanden werden: Ich finde dieses Forum sehr toll und auch gerade die tollen und oft hilfreichen Beiträge von Blackjack sind immer sehr beliebt bei mir, wenn ich mal im Forum stöbere.
Aber irgendwie ist jetzt aus einer Mücke ein Elefant geworden. Ich will einfach, dass mein Skript tut und möglichst auch - für welchen Fall auch immer - die Daten nicht verliert.
Da mein Skript eine Textdatei beschreiben soll, lag es mir jetzt nahe, lieber dort eine - vielleicht unschöne - Lösung zu suchen, als mir jetzt noch Gedanken über irgendwelche Dienste/Datenbanken zu machen.
Ob und wie viele unnötige CPU-Zyklen und Speicherzugriffe ich mir damit einhandle, ist da doch vollkommen egal. Aber hier werde ich irgendwie direkt für den Vorschlag verteufelt, ein paar unnötige Festplattenzugriffe zu verursachen (auf meinem System, auf dem eh nichts passiert).
Wenn ich jemals für ein breiteres Publikum als mich selbst entwicklen sollte, dann würde ich jedem eurer Worte bedingungslos zustimmen. Wenn ich etwas entwickle, das auch gleichzeitig Spaß beim Programmieren machen soll, würde ich auch nie so programmieren.
Ich hoffe, ihr nehmt mir diese gottlosen Blasphemien nicht zu sehr übel
@Nocta: Eben doch, das dürfte in jedem Fall dem praktisch gegangenen Weg entsprechen *nicht* selber den Sync-Vorgang zu erzwingen. Das ist eine Möglichkeit die nur für ganz wenige Spezialfälle interessant ist, und in allen anderen Fällen nichts bringt, aber schadet. Das dieser Schaden bei Dir sehr gering ist, macht es trotzdem zu einer ziemlich unsinnigen Idee das einzubauen. Speichere einfach regelmässig, zum Beispiel nach der Eingabe jeder Zeile, und vertraue darauf dass das Betriebssystem das schon so zeitnah wie es effizient möglich ist, sichern wird. Insbesondere wenn das System sonst so gut wie nichts tut, steht dem doch auch überhaupt nichts entgegen. Arbeit von Stunden kann doch nur verloren gehen wenn das System ständig über diesen Zeitraum einen Prozess hat der ununterbrochen auf die Platte zugreift und eine höhere IO-Priorität hat als Dein Programm, und/oder selber ständig synct.
Das einzige Programm an das ich mich so spontan erinnern kann was so einen Unsinn macht(e?) war der Daemon der die Bitcoin-Wallet auf den neuesten Stand bringt. Der schreibt/synct ständig jedes neue Datenpaket. Praktisches Gegenmittel: `libeatmydata` — eine Shared Library die man per `LD_PRELOAD` laden kann und die `sync()` & Co für einen Prozess durch Nulloperationen ersetzt. Vorher eine Sicherheitskopie von der Wallet-Datei zu machen und dann den Daemon mit dieser Bibliothek zu laden war *wesentlich* schonender für das System und meine Nerven.
Das einzige Programm an das ich mich so spontan erinnern kann was so einen Unsinn macht(e?) war der Daemon der die Bitcoin-Wallet auf den neuesten Stand bringt. Der schreibt/synct ständig jedes neue Datenpaket. Praktisches Gegenmittel: `libeatmydata` — eine Shared Library die man per `LD_PRELOAD` laden kann und die `sync()` & Co für einen Prozess durch Nulloperationen ersetzt. Vorher eine Sicherheitskopie von der Wallet-Datei zu machen und dann den Daemon mit dieser Bibliothek zu laden war *wesentlich* schonender für das System und meine Nerven.
Na gut, ich wusste halt beim Stellen der Frage nicht, ob es sich überhaupt so weit aufschieben kann, dass der Datenverlust relevant wird. Ich hatte mich auch gefragt, ob der vielleicht in manchen Fällen erst beim file.close() überhaupt Daten in die Datei schreibt. (Vielleicht gibt es das ja auch? Na ja, egal)
War ja nur ein Vorschlag und außerdem kann man "alle paar Sekunden bei Usereingabe syncen" wohl schwerlich mit dem von dir genannten Programm vergleichen. Wobei es immerhin eine interessante Anekdote ist
PS: Wer sich über den geänderten Account-Namen wundert, tut mir leid für die Verwirrung, hatte mal mein PW vergessen und mich jetzt ausversehen mit dem anderen wieder eingeloggt.
War ja nur ein Vorschlag und außerdem kann man "alle paar Sekunden bei Usereingabe syncen" wohl schwerlich mit dem von dir genannten Programm vergleichen. Wobei es immerhin eine interessante Anekdote ist
PS: Wer sich über den geänderten Account-Namen wundert, tut mir leid für die Verwirrung, hatte mal mein PW vergessen und mich jetzt ausversehen mit dem anderen wieder eingeloggt.
Woher sollen wir das denn wissen? Bei allgemeinen Fragen muss man nunmal davon ausgehen, dass es ein allgemeines Problem ist. Da es leider genug Anwendungen gibt die einfach nur dämlich programmiert sind muss man in eigenem Interesse auf die Probleme deiner Anforderungen hinweisen. Denn in 99% aller Fälle ist das, was du da willst, eine wirklich bescheuerte Idee. Also bevor du dich angegriffen fühlt: Woher sollen wir denn wissen wofür du das brauchst?Nocta hat geschrieben:Ob und wie viele unnötige CPU-Zyklen und Speicherzugriffe ich mir damit einhandle, ist da doch vollkommen egal. Aber hier werde ich irgendwie direkt für den Vorschlag verteufelt, ein paar unnötige Festplattenzugriffe zu verursachen (auf meinem System, auf dem eh nichts passiert).+
Hallo,
mal so eine Zwischenfrage zum Verständnis: Reicht es nicht aus, die Datei mit "with" zu öffnen? Das wird einem doch immer angeraten, weil hier die geöffnete Datei bei einer Ausnahme im Skript wieder ordnungsgemäß geschlossen wird. Und ich gehe jetzt mal davon aus, dass in einem solchen Fall die Daten, die evtl. noch im Schreibcache oder sonst wo stehen, dann noch vom Interpreter/Betriebssystem auf die Platte geschrieben werden. Oder?
Ich denke mal, zu 98% wird "nur" das Skript mit einer Ausnahme abbrechen. In den wenigstens Fällen wird der Pythoninterpreter absaufen. Und wenn das Betriebssystem dann mal abschmiert, dann ich glaub die kleine verhunzte Textdatei das kleinste Problem.
mfg
mal so eine Zwischenfrage zum Verständnis: Reicht es nicht aus, die Datei mit "with" zu öffnen? Das wird einem doch immer angeraten, weil hier die geöffnete Datei bei einer Ausnahme im Skript wieder ordnungsgemäß geschlossen wird. Und ich gehe jetzt mal davon aus, dass in einem solchen Fall die Daten, die evtl. noch im Schreibcache oder sonst wo stehen, dann noch vom Interpreter/Betriebssystem auf die Platte geschrieben werden. Oder?
Ich denke mal, zu 98% wird "nur" das Skript mit einer Ausnahme abbrechen. In den wenigstens Fällen wird der Pythoninterpreter absaufen. Und wenn das Betriebssystem dann mal abschmiert, dann ich glaub die kleine verhunzte Textdatei das kleinste Problem.
mfg
@bfm: Selbst ohne ``with`` und bei einem hart abgestürzten Python-Prozess werden normalerweise vom Betriebssystem alle offenen Dateien vom Prozess ordnungsgemäss geschlossen und dabei auch Pufferinhalte rausgeschrieben. Die Datenstrukturen von Dateien, inklusive die Puffer werden ja vom Betriebssystem verwaltet und nicht vom abgestürzten Prozess. Die Pufferinhalte gehen durch einen Prozessabsturz also nicht verloren.