![]() |
Wie funktioniert BlockRead/Write?
Ihr müsst mir mal erklären, was bei der Anwendung von BlockRead + BlockWrite genau passiert,
unter dem Gesichtspunkt der Blockgröße. Ich beschäftige mich nun frisch mit diesen Prozeduren und hab nähmlich keine genaue Vostellung davon, da alles bei Versuchen in Widersprüchen endete. BlockWrite(Datei,Zeichenkette[1],Blockgroesse); BlockWrite(Datei,Zeichenkette[2],Blockgroesse); BlockWrite(Datei,Zeichenkette[3],Blockgroesse); Gehe ich recht in der Annahme, dass wenn ich Blockgröße auf 1 setze, immer jeder Block eine bestimmte Größe hat (welche ist es) und somit die Zeichenkette abgeschnitten wird, wenn sie diesen Wert überschreitet? Wenn dies der Fall wäre, müsste ich mich auf eine Blockgröße festsetzen, da die länge der Zeichenketten unterschiedlich ist und alle in die selbige Datei geschrieben werden. Sagen wir als Beispiel mal, Zeichenkette[1] = 3 Bytes, Zeichenkette[2] = 7 Bytes, Zeichenkette[3] = 1 Byte und Blockgröße = 10 Bytes. Nun dürfte ich doch die Strings originalgetreu auch wieder einlesen können, wenn ich die richtige Blockgröße angeben? Und was hat es nun bei Reset/Rewrite mit einer eventuellen Blockgrößenangabe auf sich? Was ist, wenn ich die weglasse, bzw. angebe? Und mir ist noch etwas aufgefallen. Unter gewissen Umständen funktionierte ja fehlerfreies Schreiben+Einlesen (genau das ist ja für mich das Rätsel, da ich bei beiden Versuchen keinen Unterschied erkenne). Jedenfalls, bei dem funktionierenden Test brach das Programm durch eine Zugriffsverletzung ab, wenn ich dem Stringbezeichner, welcher zum Wiedereinlesen verwendet wurde, vorher noch nie einen Wert zugewiesen habe. Also wenn ich dann einfach nur vorher der Zeichenkette := ' ' , funktionierte alles einwandfrei. (?!) Also nochmal zusammengefasst: Ich möchte mehrere Strings unterschiedlicher länge in eine untypisierte Datei schreiben und wieder so, wie sie vorher waren, einlesen können. Die Blockgröße ist nun das größte Rätsel für mich. Ich hoffe ihr versteht, was mein Problem ist, und wo der Gedakengang falsch war, weil mir vielleicht eine Information fehlt oder ich die Sache komplett missverstanden habe. In diesem Sinne, machts mal ganz gut! PAX [edit=Luckie] Mfg, Luckie[/edit] |
Re: Wie funktioniert BockRead/Write?
Hallo,
ich verstehe nicht ganz was du da geschrieben hast.. soll Zeichenkette ein String sein oder ein array of string? Das BlockWrite schreibt einfach Blockgroesse Bytes von der Adresse der Variable die du ihm gibst. Dabei ist zu beachten das die Variable selbstständig referenziert wird - wenn du also einen Pointer auf deine Daten hast mußt du sie vorher dereferenzieren. Beispiele:
Delphi-Quellcode:
Hoffe ich hab mich halbwegs verständlich ausgedrückt...
var
h: String; g: array of String; BlockWrite(Datei, "Muhh", 4); // Schreibt Muhh in die Datei BlockWrite(Datei, h[1], length(h)); // Schreibt den Inhalt von h in die Datei BlockWrite(Datei, PChar(h)^, length(h)); // Schreibt den Inhalt von h in die Datei BlockWrite(Datei, g[1][1], length(g[1])); // Schreibt den Inhalt des 1. Strings des Arrays in die Datei BlockWrite(Datei, g[2][1], length(g[2])); // Schreibt den Inhalt des 2. Strings des Arrays in die Datei [edit] Wo Variable g stehen sollte auch wirklich g hingeschrieben... [/edit] |
Re: Wie funktioniert BockRead/Write?
Ok, das ist ja schonmal sehr informativ, was ich da höre :) . Also dankschön erstmal. Ja, mit Zeichenkette meinte ich nur einzelne Strings (aber kein Array). h ist nun das Array in deinem Beispiel. Was für mich jetzt wieder noch neu ist, ist die zweite Indexangabe des Arrays im Beispiel (h[1][2]). Was hat die 2. Indexangabe für eine Bedeutung? Und bei der Blockgröße, wenn ich dann immer dafür die Länge der aktuell reinzuschreibenden Variablen angebe, werden dann die einzelnen Blöcke unterschiedlich groß in der Datei? Wie lese ich das dann wieder vernünftig ein, wenn ich nicht weiß, wie groß die dann immer sind.
Aus dem ersten Beispiel mit 'Muuh' leite ich ab, dass die Blockgröße wirklich in Byte angegeben wird (hier: 4). Wenn ich bei dieser Methode nun 3 angegeben hätte, würde dann zum Schluss in der Datei nur 'Muu' stehen? Und dieses PChar(), zerlegt es den String dann einfach nur? Und schreibt er die Teile dann alle in Extrablöcke? Ich weiß dann aber beim Einlesen nicht, wieviele Blöcke zum selbigen String gehörten. UNd ich seh gerade, da is ja noch ein Zeiger, damit kann ich zur Zeit auch noch nicht mit umgehen. Was spielt sich dort abß Ich danke dir PAX |
Re: Wie funktioniert BockRead/Write?
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Delphi-Quellcode:
h:='Muhh';
h[1] = 'M'; PChar(h)^ = 'M'; // bzw. die Adressen sind auch gleich: @h[1] = PChar(h); |
Re: Wie funktioniert BockRead/Write?
Wenn ich eine größere Blockgröße angebe, als der String lang ist, dann wird sicherlich der Rest nicht mit ' ' aufgefüllt. Das bedeutet also, ich müsste vorher manipulativ den String auf die gewünschte Größe bringen?
|
Re: Wie funktioniert BockRead/Write?
Den müsstest du selber auffüllen - ja. Sonst wird entweder Müll dahinter geschrieben, oder im schlimmeren Fall gibts eine AV - währscheinlicher ist aber der Müll :).
Wenn du aber weisst wie lang die Strings jeweils werden, böte es sich an mit ![]() ![]() Gruss, Fabian |
Re: Wie funktioniert BockRead/Write?
|
Re: Wie funktioniert BockRead/Write?
Ich danke euch! :)
Unter welchen Voraussetzungen kann es passieren, dass die Variable, in der ich etwas einlese, "keinen verfügbaren Wert" enthält? Ich hab jetzt die Variante mit dem Trennzeichen ausgewählt. Ich schreibe die entsprechenden Sachen in die Datei und filtere beim Einlesen die einzelnen Strings durch das Trennzeichen heraus. Das ganze Programm bricht immer mit einer Zugriffsverletzung ab, sobald verglichen wird, ob das eingelesene Zeichen dem Trennzeichen entspricht (bei Vergleich nach <> kein Abbruch) (If s = Trennz Then...). Ich hab dann mal überprüft, welchen Wert die Einlesevariable zu dem Zeitpunkt hat, und zwar gar keinen. Woran liegts nun? |
Re: Wie funktioniert BockRead/Write?
Bevor wir anfangen zu raten, poste doch mal deinen Code :mrgreen:
|
Re: Wie funktioniert BockRead/Write?
Delphi-Quellcode:
var EinleseString: String;
zweiteListBox: boolean; begin EinleseString:=' '; //wenn der Einlesestring vorher noch einen Wert zugewiesen bekommen hat, Vokabel:=''; //dann bricht das Prog beim Einlesen auch ab zweiteListBox := false; OpenDialog1.Execute; AssignFile(Datei,OpenDialog1.FileName); Reset(Datei); While not EOF(Datei) do begin BlockRead(Datei,EinleseString,1); If EinleseString <> '¿' Then begin Insert(EinleseString,Vokabel,Length(Vokabel)) end; If EinleseString = '¿' Then begin //mit genau dieser Zeile kommt er nicht klar If zweiteListBox = true Then begin ListBox2.Items.Add(Vokabel); Vokabel:=''; zweiteListBox := false; end else begin ListBox1.Items.Add(Vokabel); Vokabel:=''; zweiteListBox := true end; end; end; CloseFile(Datei); end; |
Re: Wie funktioniert BockRead/Write?
Hallo,
hier mal ein paar Änderungen am Code:
Delphi-Quellcode:
Es gab bei deiner Version immer eine AV da dein EinleseString falsch verwendet wurde. Du müßtest den imho mit EinleseString[1] angeben damit es richtig funktioniert, oder halt nur einen Char-Typ nehmen - du liest ja immer nur ein Zeichen.
var EinleseString: Char; // wir lesen sowieso immer nu einzelne Zeichen - brauchen also nicht unbedingt einen String
zweiteListBox: boolean; begin Vokabel:=''; //dann bricht das Prog beim Einlesen auch ab zweiteListBox := false; OpenDialog1.Execute; // <--- Du solltest hier schauen ob das nicht false zurückgibt, dann hat der Benutzer nämlich abbrechen gedrückt! AssignFile(Datei,OpenDialog1.FileName); Reset(Datei); // <---- Was ist denn wenn's einen Fehler gibt?! // Rest wie oben. end; |
Re: Wie funktioniert BockRead/Write?
Ich habe mir mal erlaubt das Topic zu korrigieren. :roll:
Zitat:
|
Re: Wie funktioniert BlockRead/Write?
Jetzt wird die While-Schleife wenigstens ein paar mal durchlaufen :lol: (war glaub ich vorher nicht so). Das Prolbem ist nur, dass ich dann via Haltepunkte beim Kontrollieren des eingelesen Zeichens feststellte, dass ich vorher in die DAtei nicht solche Zeichen geschrieben hatte. Und dann, wenn irgendwann der Einlesestring einen "nicht verfügbaren" Wert hat, bricht das Programm beim Vergleich EinString = '¿' mit AV ab.
Naja, jedenfalls scheint das nicht die Wurzel des Problems zu sein, denn mir fiel in der Hilfe auf, dass bei der Prozedur Rewrite optional die Blockgröße angegeben werden kann. Falls man dies nicht tut (so wie ich), dann ist der Standardwert 128 gesetzt. Und das ist die Wurzel allen Leids (@ Ausdrucksweise: sorry, ich glaub die is nur bei allmystery.de angemessen). Ich möchte eine feste Blockgröße garnicht angeben, da ja die zu schreibenden Strings unterschiedlich groß sind. Sie sollen hintereinander (Zeichen für Zeichen) in dieser Datei stehen, ohne Leerzeichen/Nichts (oder was auch immer). Geht das irgendwie? Ich könnte ermitteln, was der längste String ist, aber dann stehen ja zum Schluss nach den kürzeren Strings immer noch die Leerzeichen, damit die angegebene Blockgröße übereinstimmt. (?) Danke für euren Einsatz :) @Luckie: Ups... Danke fürs Ändern :) |
Re: Wie funktioniert BlockRead/Write?
Hallo,
Zitat:
|
Re: Wie funktioniert BlockRead/Write?
Hurra, es hat das erste mal geklappt, zwei Strings in die Datei zu schreiben und sie wieder einzulesen und sogar in die ListBoxen einzufügen (ohne AV!)! :cheers:
Die Variante, bei Rewrite/Reset als Blockgröße 1 anzugeben war korrekt. Ich dachte nur, dass der eventuell längere string sonst abgeschnitten wird (war aber nicht so). Naja, nur es sind nicht die ASCII-zeichen, die ich vorher in die LB eingetragen habe. Ich versuch hier mal ne Tabelle zu machen, welche das veranschaulicht: geschriebener Wert eingelesener Wert kommentar A ein bisschen fetter B $ Dollarzeichen C (siehe oben) D $ (siehe oben) wie gesagt, es sind nicht die originalcharacter. auffällig: die verfälschten strings haben in listbox1 alle den selben wert und in listbox2 sind sie anders als jene in LB1, aber wiederum untereinander in LB2 gleich. jepp, und genauso wie sie eingelsen aussehen, schauen sie auch direkt in der datei aus. also lief beim schreiben in die datei was falsch. um die strings zu ermitteln benutze ich listbox1.items.strings[i], is doch ok, oder? außerdem hängt das programm für ca. 20 sekunden, wenn ich einlese. leute, ich sag euch, es ist alles recht seltsam. aber ich bin ja jetzt schon ein ganze stück weiter :lol: , dank euch. zusammen schaffen wir das schon 'g'. :cheers: PAX |
Re: Wie funktioniert BlockRead/Write?
ok, das mit der tabelle macht er wohl.
aus "A" wurde "" (ein bisschen fetter) aus "B" wurde "$" (Dollarzeichen) aus "C" wurde "" (siehe oben) aus "D" wurde "$" (siehe oben) |
Re: Wie funktioniert BlockRead/Write?
Zitat:
|
Re: Wie funktioniert BlockRead/Write?
Delphi ist verhext. Beim schreiben des Strings hat er noch den exakten Wert, aber geschrieben werden dann doch andere ASCIIs. Liegts vielleicht an der Charset-Einstellung (die von den ListBoxen ist auf irgedwas mit "default" gestellt)?
Ihr könnts euch nicht erklären, ich kanns mir nicht erklären... :( Soll ich darüber ein neues Thema aufmachen? (hier guckt sowieso keiner rein, der über diese letztere Problematik etwas sagen könnte) PAX :kotz: PS: Ähm, ListBox.Items.Strings[fuck] kann ich nicht direkt in die BlockWrite-Prozedure reinschreiben, also mach ich folgendes:
Delphi-Quellcode:
var Vokabel: string;
Vokabel := ListBox1.Items.Strings[i-1]; BlockWrite(Datei,Vokabel,Length(Vokabel)); |
Re: Wie funktioniert BlockRead/Write?
Hä? Ich hab jetzt mal (wie du es gesagt hast) Vokabel[1] geschrieben,... es läuft?!! lol, versteh ich nich. Vokabel is doch nicht als Array deklariert? was heißt denn dieser Index 1 dort?
Dann dankeschön! Also, ich hab jetzt grad absolute dopaminausschüttung... Vielen Dank! Kleines/(großes) Problem beseitigt, hilfsbereite Leute, Thema abgeschlossen! :cheers: Machts mal ganz gut! PAX :-D |
Re: Wie funktioniert BlockRead/Write?
Du kannst in einer string-Variable auf die einzelnen Zeichen Zugriff erhalten.
Angenommen der String MeinString ist 'Hallo!'. Dann wäre MeinString[1] also H, MeinString[3] dann l, und eben so weiter. Also gibt dir string[n] das n-te Zeichen eines Strings aus ;-) |
Re: Wie funktioniert BlockRead/Write?
Müsste er dann nicht alleine das einzelne Zeichen an dieser Stelle in die Datei schreiben? Also wenn:
f:='delphi'; blockwrite(datei,f[1],length(f)); --> in datei: 'd' |
Re: Wie funktioniert BlockRead/Write?
Ja, so siehts aus.
Das gleiche isses, wenn du in nen Stream schreiben willst, aber das gehört nicht hierher ;-) |
Re: Wie funktioniert BlockRead/Write?
Macht er glücklicherweise nicht :) . er schreibt dann 'delphi' in die Datei?!
PAX |
Re: Wie funktioniert BlockRead/Write?
Probiers doch :-P
|
Re: Wie funktioniert BlockRead/Write?
:-D Er schreibt dennoch den gesamten String bei mir lol. Wenn ich aber zum Beispiel der caption vom formular den wert eines strings (mit solch einer indexangabe) zuweise, dann ist es wirklich nur dieses eine zeichen. aber blockwrite schreibt den gesamten string. :?
it's magic |
Re: Wie funktioniert BlockRead/Write?
Tja, so isses ;-)
|
Re: Wie funktioniert BlockRead/Write?
Hallo,
wenn du einen meiner ersten Posts ließt, da steht das er die Variable die du dem BlockWrite/Read übergibst selbstständig referenziert (also in eine Adresse umwandelt). Ein String ist aber nur ein Zeiger (eine Adresse) auf ein Array of Char mit ein bißchen Delphi Black-Magic drumrumm das du im normalfall nix mit dem Array am Hut hast. Wenn du jetzt nur den String übergibst, dann schreibt er die Adresse des Zeigers in die Datei und produziert wenn du Glück hast noch ne AV. |
Re: Wie funktioniert BlockRead/Write?
Tja, dann würd ich mal sagen: Vorher einen Bannkreis ziehen und die Telefonnummer von nem guten Exorzisten+Psychater bereithalten :) .
Gut, vielen Dank, ihr habt mir geholfen das Problem zu lösen. :) Bis zum nächsten Hexen-/Delphianertreffen! :twisted: PAX |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:20 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-2025 by Thomas Breitkreuz