Entwickler-Ecke
Dateizugriff - End of File Problem
Toastbrotbaby - Di 26.10.10 18:42
Titel: End of File Problem
Moin,
nachdem ich nun eine ganze Weile nichts mehr gebastelt hatte schreibe ich grad an einem neuen kleinen Tool.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| procedure TForm1.positionieren(datensatz: integer); var aktdatensatz: Archiv;
begin if (datensatz<0) or (datensatz>FileSize(datei)) then exit else begin seek(datei, datensatz); read(datei, aktdatensatz); if aktdatensatz.bild =('') then else Image1.Picture.LoadFromFile(aktdatensatz.bild); Memo1.Lines.Text:= aktdatensatz.beschreibung; end; end; |
Mit Hilfe von dem schönen Forum hier und dem einen oder anderen Tutorial hab ich es dann doch noch geschafft diese Prozedur hier hin zu tippen.
Und nun kommt mein eigentliches Problem.
Wenn ich nun mehrere Datensätze eingebe und einen Testlauf starte funktioniert das ganze auch echt gut. Bis auf den Mediaplayer, aber der ist bis jetzt noch relativ unwichtig.
Aber wenn man ich nun am Letzten Datensatz bin und zum nächsten Datensatz weiter klicke kommt die Fehlermeldung Read beyond end of File. Dies stört den Ablauf irgendwie erheblich. Und jetzt sitz ich hier und grübel und suche ... aber ich glaub ich seh den Wald vor lauter Bäumen nicht mehr.
Hat mal jemand einen kleinen Stubbser, oder auch nen großen?!
Des Rätsels Lösung ist mit Sicherheit total einfach ...
Greetz
Toasty
Gammatester - Di 26.10.10 19:43
Filesize liefert die Dateigröße in Bytes nicht in Datensätzen. Die Anzahl der Datensätze ist FileSize(datei) div sizeof(aktdatensatz).
jaenicke - Di 26.10.10 19:58
Gammatester hat folgendes geschrieben : |
| Filesize liefert die Dateigröße in Bytes nicht in Datensätzen. Die Anzahl der Datensätze ist FileSize(datei) div sizeof(aktdatensatz). |
Das stimmt nicht, schau einmal in die Hilfe. ;-)
Wie sieht denn ein Datensatz aus?
Toastbrotbaby - Di 26.10.10 20:08
@jaenicke
War deine Frage wie ein Datensatz aussieht an mich gerichtet?
jaenicke - Di 26.10.10 20:13
Ja, aber den Fehler sehe ich auch schon.
Nehmen wir an du hast 3 Datensätze: 0, 1 und 2
Was liest du? 0, 1, 2 und 3...
Denn du prüfst auf kleiner 0 und größer als Anzahl.
Was ich mich aber vor allem frage: wozu das ständige seek?!?
Toastbrotbaby - Di 26.10.10 20:23
ich glaub ich steh grad komplett aufm schlauch ...
wenn ich das richtig verstanden habe wird seek doch dazu verwendet um die positionierung vorzunehmen oder?!
jaenicke - Di 26.10.10 20:49
Richtig, aber es las sich so, als würdest du einen Datensatz nach dem anderen durchgehen. Und dann brauchst du das ja nicht.
Ansonsten musst du eben nur aus dem "größer als FileSize" ein "größer gleich FileSize" machen.
Toastbrotbaby - Di 26.10.10 20:51
also müsste die prozedur so aussehen
Delphi-Quelltext
1: 2:
| if (datensatz = FileSize(datei)) then positionieren(datensatz(0)); |
bin ich da jetzt langsam wieder in der spur?
Edit: bzw (datensatz <> FileSize(datei)) müsste korrekt sein glaub ich oder?!?
jaenicke - Di 26.10.10 21:42
Toastbrotbaby hat folgendes geschrieben : |
| also müsste die prozedur so aussehen |
Ja, zum Beispiel, wobei die Null ja wohl direkt an positionieren übergeben werden muss.
Aber da sind wir doch genau wieder da, was ich am Anfang vermutet habe. Du gehst doch einfach der Reihe nach durch, oder? Anders macht der Codeschnippsel doch keinen Sinn.
Und dann kannst du dir das ganze positionieren sparen, nur wenn du am Ende angekommen bist, musst du wieder zum Anfang...
Toastbrotbaby hat folgendes geschrieben : |
| Edit: bzw (datensatz <> FileSize(datei)) müsste korrekt sein glaub ich oder?!? |
Dann akzeptierst du ja auch größer als. Ich habe doch schon geschrieben... kleiner gleich... :roll:
Toastbrotbaby - Di 26.10.10 21:50
das mit dem <> hatte ich grad nur so halb im kopf und dachte das irgendwo gelesen zu haben.
werd das nachher mal probieren wie ich das zuerst im letzten beitrag geschrieben habe ... vlt klappt das ja :)
bin da grad recht optimistisch
greetz
ps: wenn das klappt sag ich schon mal danke :)
Toastbrotbaby - Di 26.10.10 22:59
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| procedure TForm1.Image2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var datensatz: integer; begin
if Button = mbmiddle then MediaPlayer1.Play; if Button = mbmiddle then Panel1.Visible:=true; case button of
mbleft: positionieren(FilePos(datei)-2);
mbright: if datensatz = FileSize(datei) then positionieren(0); else positionieren(FilePos(datei));
end; |
Sodele das ist die Prodezur die ich grad mal gebastelt hatte ...
funktioniert in soweit ganz gut, als das mbleft funktioniert ... mbright leider gar nicht ...
was dazu kommt die case of geschichte mag bei mir nur 1 anweisung laufen lassen, die 2. wird ignoriert ... hab ich da was vergessen was zu beachten ist wenn ich eine 2. anweisung laufen lassen will zb
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| case Button of
mbleft: positionieren(FilePos(datei)-2);
mbright:
mbmiddle: MediaPlayer1.Play; Panel1.Visible:=true; |
Glaub ich bin auch grad zu müde für so nen krams ...
Vielleicht hat ja noch jemand paar Anregungen für mich.
Greetz
elundril - Di 26.10.10 23:16
wie wäre es so?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure TForm1.Image2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var datensatz: integer; begin case Button of mbmiddle: begin MediaPlayer1.Play; Panel1.Visible:=true; end; mbleft: positionieren(FilePos(datei)-2); mbright: if datensatz <= FileSize(datei) then positionieren(FilePos(datei)); else positionieren(0); end; end; |
ungetestet, einfach nur aus dem gedächnis geschrieben.
lg elundril
Toastbrotbaby - Mi 27.10.10 20:04
Moin,
ich hab das spontan mal getestet was du geschrieben hattest.
habe da auch ein paar mal dran rum gefrickelt ...
dies und das getestet ...
im endeffekt ...
nüscht is ...
vor dem else nen ; ist tatsächlich ne ganz prickelnde idee. lässt sich zwar starten, aber hat zur folge, dass spontan erstmal der button ne reaktion von 0 an den tag legt.
; dann mal kurz entfernt und siehe da ... es funktioniert zwar der button ... aber es gibt nur eine reaktion und das ist die positionieren(0) nummer.
hab dann mal ein wenig ausprobiert, aber so richtig prall ist das nicht.
was als alternative noch gehen würde, wäre wenn schlichtweg einfach die fehlermeldung read beyond end of file unterdrückt wird und man regulär weiter machen kann mit vor und zurück und start/stop ...
das wurmt mich hier grad.
Greetz
Stundenplan - Mi 27.10.10 20:32
Das ist das
DANGLING-ELSE-PROBLEM, wenn auch in abgewandelter Form:
case hat nämlich selbst auch einen Else-Zweig, welcher augeführt wird, wenn keine anderen Bedingungen greifen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| var i: Integer; i := 4; case i of 1: DoSomething; 2: DoSomething2; else DoSomethingElse; end; |
Und Delphi nimmt an, dass das Else zum Case-Zweig gehört (oder auch nicht; hängt vom Semikolon ab). Du könntest einen Begin-End-Block um die If-Abfrage machen, dann sollts gehen.
Toastbrotbaby - Mi 27.10.10 22:07
So ich hab jetzt mittlerweile die prozedur so gebaut:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| procedure TForm1.Image2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var datensatz: integer;
begin case button of
mbleft: positionieren(FilePos(datei)-2);
mbmiddle: begin MediaPlayer1.Play; Panel1.Visible:=true; end;
mbright: begin if datensatz <= FileSize(datei) then positionieren(FilePos(datei)) else positionieren(0);
end; end; end; |
funktioniert ja ganz gut ... aber mbright fängt offenbar nur den else befehl ab ...
was mir noch so in den kopf geschossen ist, war die frage woher die prozedur weiß, wie groß die variable datensatz ist ... es soll ja wenn die variable größer oder gleich ist zum nächsten eintrag springen und ansonsten wieder auf 0 setzen ...
es macht mich irre ...
jaenicke - Mi 27.10.10 22:10
Toastbrotbaby hat folgendes geschrieben : |
| woher die prozedur weiß, wie groß die variable datensatz ist ... |
Die gehört ja auch als Feld oben unter private und nicht als lokale Variable deklariert, die den Wert bei jedem Aufruf wieder verliert.
Toastbrotbaby - Mi 27.10.10 22:56
das ist ja mal echt zum mäuse melken ...
egal ob die variable lokal oder global oder sonst was ist ... in welcher reihenfolge auch immer ich die if geschichte auf dem rechten maus button laufen lasse ...
es kommt immer diese nervige "read beyond end of file" fehlermeldung ...
plan b wäre jetzt ...
wie unterdrücke ich die meldung und sorge dafür das schlichtweg einfach gar nichts passiert?!? sollte nur kein fenster aufgehen mit ner meldung drin ... solange da einfach nix passiert wäre das noch akzeptabel.
greetz
jaenicke - Do 28.10.10 05:42
Toastbrotbaby hat folgendes geschrieben : |
egal ob die variable lokal oder global oder sonst was ist ... in welcher reihenfolge auch immer ich die if geschichte auf dem rechten maus button laufen lasse ...
es kommt immer diese nervige "read beyond end of file" fehlermeldung ... |
Wenn du den aktuellen Datensatz da nicht reinschreibst, klappt das auch nicht. In deinem letzten Code greifst du nur einmal lesend auf die Variable zu. Also kann die auch nie zu groß sein.
Hast du es eigentlich einmal mit EoF versucht? Ich weiß nicht, ob das für tpisierte Dateien geht (hab son Zeug nie benutzt^^), aber wenn ja, kannst du direkt prüfen, ob du dich am Dateiende befindest.
Generell solltest du dich einfach mal mit dem Debuggen auseinandersetzen. Denn das hast du bisher ja offenbar nicht getan, sonst wüsstest du ja was passiert...
http://www.delphi-treff.de/ueber-delphi/entwicklungsumgebung-bis-delphi-7/debugger/
Toastbrotbaby - Do 28.10.10 15:14
moin,
ich hab letztens tatsächlich schon mal nach eof geschaut, aber habs damit aus mir nicht erklärbaren nicht hinbekommen.
hab jetzt nochmal gesucht und was getestet ...
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| procedure TForm1.Image2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin case button of
mbleft: positionieren(FilePos(datei)-2);
mbmiddle: begin MediaPlayer1.Play; Panel1.Visible:=true; end;
mbright: while not EOF(datei) do begin positionieren(FilePos(datei));
end; end; end; |
und zack ... es geht ...
das war jetzt wirklich mal ne mücke zu nem elefanten gemacht ...
danke an euch.
Greetz
Edit: eine kleinigkeit noch, aber das werd ich bei gelegenheit mal tun ... beim ersten start springt das programm direkt zum aktuell 2./letzten datensatz ... keine ahnung wieso, aber das is mir grad recht egal, die generelle funktionalität ist gegeben.
jasocul - Mo 01.11.10 09:54
Delphi-Quelltext
1:
| mbleft: positionieren(FilePos(datei)-2); |
Vermutlich, weil du auf dem Image2 irgendwo den linken Maus-Button drückst.
Von alleine steht eine typisierte Datei beim Öffnen immer am Datei-Anfang.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!