Random Access Dateien - Nostalgie läßt grüßen

  • Hallo,

    Für die Nostalgiker unter euch, habe ich eine Art Random Access Datei aus Bereichen gemacht.

    Etwa wie früher aus BASIC gewohnt. Statt FIELD .... geht es hier mit STRUCT.

    Probiert mal aus, ob ihr noch einen Fehler findet. Ansonsten ist es mal ein Anfang.

    Wir sind die XProfaner.

    Sie werden von uns assimiliert.

    Widerstand ist zwecklos!

    Wir werden alle ihre Funktionen und Algorithmen

    den unseren hinzufügen.

    • Anzeige

    Hallo!

    Wenn du gerade an deiner Website arbeitest oder dein aktuelles Hosting überdenkst: Wir betreiben mit NetzLiving eine Hosting-Plattform, die speziell auf Performance, Sicherheit und einfache Verwaltung ausgelegt ist.

    • ✔️ Schnelle Ladezeiten (optimiert für WordPress, WoltLab & Co.)
    • ✔️ Deutsche Server & DSGVO-konform
    • ✔️ Persönlicher Support (kein 0815-Ticket-System)

    Mehr erfahren

  • Ich habe das Programm noch um eine Löschfunktion erweitert.

    Wenn man im Grid einen Eintrag wählt, soll dieser gelöscht werden.

    Die Datensätze stehen in einem Array mit Structur. Gelöscht wird mit

    ArrDel ..... Die Datei wird Erase #1 gelöscht und dann neu eingelesen.

    Der Eintrag scheint auch im Array gelöscht zu werden, aber beim Neueinlesen

    stimmt was nicht.

    Kann jemand meinen Denkfehler (Knoten) lösen ?

    Wir sind die XProfaner.

    Sie werden von uns assimiliert.

    Widerstand ist zwecklos!

    Wir werden alle ihre Funktionen und Algorithmen

    den unseren hinzufügen.

  • Ich habe das Problem mal nachvollziehbar gemacht.

    Offensichtlich löscht Erase #|datei nicht richtig. Der letzte Eintrag der Datei

    kommt dann immer zweimal. Auch ein Rewrite hilft da nicht.

    Wenn man mit einem Texteditor die Datei anschaut, ist der Datensatz mit "Käse"

    auch zweimal vorhanden, aber wieso ? Der ist doch nur einmal geschrieben worden.

    Auch ein Assign datei, "", das das Dateihandle löscht, brachte nichts.

    Mache ich da jetzt was falsch oder ist meine Vermutung richtig ?

    Wir sind die XProfaner.

    Sie werden von uns assimiliert.

    Widerstand ist zwecklos!

    Wir werden alle ihre Funktionen und Algorithmen

    den unseren hinzufügen.

    Einmal editiert, zuletzt von H.Brill (26. November 2023 um 13:25)

  • Mit den Datei-Funktionen habe ich letztens auch gekämpft. Bei mir war es das Problem, dass bei Rewrite durch weniger Daten als zuvor eben nicht (wie gewünscht und erwartet) der bisherige Dateiinhalt verloren ging sondern der Überhang übrig blieb, weshalb ich dann auch so Erase gewechselt bin.

    In deinem Fall scheint es Folgendes zu sein:
    Erase möchte nicht mit jedem Dateimodus (OpenRW?) zusammenarbeiten. Folgendes hilft:
    Schließe die Datei, wenn du mit Lesen oder schreiben fertig bist und lösche sie dann erst mit einem eigenen Assign:

    Code
     Assign #1, $ProgDir + "Mitarbeiter.dat"
     Erase #1
     Close #1

    Da ich bei mir irgendwie den Debugger nie zum Laufen bringe, arbeite ich normalerweise mit einer eigenen Konsolenausgabe oder in einfachen Fällen auch mal mit messageboxes als Breakpoints, so konnte man relativ schnell feststellen, dass die Datei zu keinem Zeitpunkt gelöscht wurde.

  • Das scheint auch nicht zu funktionieren. Hatte auch schon mit Set("FileMode", N)

    rum gespielt. Früher gab es mal in Turbo Pascal den Befehl TRUNCATE, der eine

    angebene Anzahl Bytes hinten an der Datei abschnitt. Wenn man vorher durch geschicktes

    Umsortieren den zu löschenden Datensatz ans Ende schob, wurde der dann gelöscht.

    Wenn man denn auch ein richtiges FileHandle hätte, könnte man mit der Kernel32.dll

    und der File-Api das End Of File neu setzen. Geht aber wegen des echten fehlenden Handle

    nicht. Es gibt ja nur Kanal-Nummern von 1-99. Auch die Funktion Assign() gibt nur eine

    solche zurück. Und alle Dateioperationen mit API machen, möchte ich auch nun wieder nicht.


    Ich vermute mal, daß RGH einen profaninternen Speicher nicht freigibt, bzw. beim

    wiederholten Schreiben nicht dementsprechend neu dimensioniert. Somit bleiben auch

    Reste, wenn der neu zu schreibende Bereich, den wir dann neu dimensionieren, halt

    kleiner, als der alte profaninterne ist. Ob RGH vergessen hat, dies zu berücksichtigen,

    oder ob es gar nicht vorgesehen war, bleibt halt offen. Wir haben ja mehrer Bereiche,

    wie RegEx, Json, openGL usw., die nur rudimentär implementiert sind.

    Wir sind die XProfaner.

    Sie werden von uns assimiliert.

    Widerstand ist zwecklos!

    Wir werden alle ihre Funktionen und Algorithmen

    den unseren hinzufügen.

  • Hm... bei mir wurde die Datei vorher nicht gelöscht und nach dem Fix wurde sie gelöscht. Dann musst du etwas granularer debuggen. Das Löschen des Array Eintrages hatte ich zumindest validieren können, das hatte geklappt.

  • Hallo,

    Endlich klappt auch das Löschen von Datensätzen in der Datei. Statt mit einem Array zu hantieren, wird nun einfach der Inhalt der Gridbox nach einem DeleteString(handle, nr) in die Datei neu geschrieben. Ich öffne nun auch nur einmal die Datei, lösche sie mit Erase #1 und öffne sie wieder mit OpenRW #1. Dann schreibe ich sie normal mit BlockWrite. Siehe Proc RDelete().

    Woran das nun genau lag, kann ich nicht sagen. Jedenfalls funktioniert es so.

    Wir sind die XProfaner.

    Sie werden von uns assimiliert.

    Widerstand ist zwecklos!

    Wir werden alle ihre Funktionen und Algorithmen

    den unseren hinzufügen.

  • Hier ist nochmals eine Verbesserung. Das Löschen einen Datensatzes in der Datei habe ich dadurch erreicht, daß ich alle Datensätze, außer dem zu löschenden, einzeln lese und in eine neue Datei gleichzeitig reinschreibe. Danach wird die original Datei mit Erase gelöscht und wieder geöffnet und die neue Datei gelesen und gleichzeitig wieder in die Ursprungsdatei geschrieben. Am Ende wird dann noch die temporale Datei gelöscht und das Handle mit Assig #2, "" wieder frei gegeben.

    Ich habe die Proc allgemein gehalten, sodaß man im Hauptprogramm nur die Struktur erstellen und mit einem Bereich dimmen muß Ähnlich halt, wie bei GW-BASIC / Quickbasic der Field - Befehl. Anschließend muß man noch ein Assign auf die Datei machen.

    Viel Spaß damit

    PS:

    Was mich noch interessieren würde, ob das auch mit einer originalen GW-BASIC - Datei funktioniert. Also eine, die noch mit MS-DOS erstellt wurde. Es soll ja noch Leute geben, die ihre alten Schätze gerne in die Windowswelt retten wollen. Also, wer sowas noch hat, kann sie mir gerne mal zur Verfügung stellen. Ich will jetzt nicht unbedingt noch eine DOS-Box installieren und ein Laufwerk mounten. Kann dann sein, daß man dann noch mit OemToAnsi$(), AnsiToOem$() arbeiten muß, da damals ja noch keine abschließende Nullbytes hinter den Strings waren. Da die Zeichen und Zahlen ja an den gleichen Stellen im Zeichensatz stehen, würde evtl auch ein Char$(bereich, 0, anzahl) funktionieren. Das müßte man dann sehen.

    Wir sind die XProfaner.

    Sie werden von uns assimiliert.

    Widerstand ist zwecklos!

    Wir werden alle ihre Funktionen und Algorithmen

    den unseren hinzufügen.

    Einmal editiert, zuletzt von H.Brill (18. November 2024 um 10:20)

  • Was nun ältere Dateien aus der DOS-Zeit betrifft, könnte es Probleme geben, da DOS bzw. GW-BASIC ja keine Strings mit Nullbytes kennt und da evtl. über die Offsets hinaus gelesen bzw. geschrieben wird.

    Da (X)Profan mit Bereichen in Bereichen genauso gut umgehen kann, ist es besser, den Speicherbereich-Typ # statt $ zu verwenden. Ich denke, genau so verhälts es sich auch mit den Zahlen in einem DOS - 16Bit Systen (damals das neueste) . Da sollte man das & auch gegen das % vertauschen. Die Umstellung ist ja schnell gemacht :

    Code
    Struct Mitarbeiter = Name#(30), Vorname#(30), Gehalt%, Abteilung#(256)
    With Personal
      .Name# = GetText$(edit1)
      .Vorname# = GetText$(edit2)
      .Gehalt% = Val(GetText$(edit3))
      .Abteilung# = GetText$(edit4)
    EndWith

    Damit würden dann die Member der Struktur immer an der richtigen Stelle stehen. Ich wollte ja zuerst die DOS-Box installieren, bin aber davon abgekommen. Die DOS-Box ist ja wohl auch mit 32Bit geschrieben worden und wird Strings mit Nullbytes verwenden. Ob das nun mit den alten Randomdateien funktioniert, wird man nur heraus bekommen, wenn man alte Dateien hat, die vom echten DOS-Betriebssystem geschrieben worden sind. Soweit mal meine Gedanken dazu.

    Weiß jemand, ob der Field-Befehl damals nur mit Strings oder auch mit Zahlen bestückt werden konnte ? Soweit mir noch bewußt ist, konnte man da auch nur Strings ($) speichern, die mit RSet zurecht gerückt wurden. Das würde die Sache dann noch vereinfachen, man hätte eine Struktur nur mit Bereichen.

    Wir sind die XProfaner.

    Sie werden von uns assimiliert.

    Widerstand ist zwecklos!

    Wir werden alle ihre Funktionen und Algorithmen

    den unseren hinzufügen.

    2 Mal editiert, zuletzt von H.Brill (21. November 2024 um 11:20)

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!