| Autor |
Beitrag |
Blackbird
      
Beiträge: 54
|
Verfasst: Mi 21.01.04 16:44
Hallo an alle!
Folgendes Problem:
Beim sichern meiner Daten auf CD sind Fehler beim Brennen aufgetreten.
D.h.: Eine Datei auf der CD ist Defekt, sie kann nicht gelesen werden.
Ich kann aber ihre Größe ermitteln und sie öffnen - bloß lesen kann ich sie nicht.
Nun wollt ich ganz fix ein Prog schreiben, welches die ganze CD durchgeht, alle Dateien kurz öffnet, einliest (in den RAM) um zu überprüfen ob meine Daten richtig gebrannt wurden. Da stellt sich mir folgendes Problem entgegen: Ist eine Datei wirklich defekt - stürtzt mir das Programm ab - da hilft kein Try/Except Block oder ähnliches.
Kann mir da jemand weiterhelfen ?
Moderiert von Peter Lustig: Topic Verschoben
|
|
grayfox
      
Beiträge: 800
win98, winXP
D4 Standard; D6 Personal
|
Verfasst: Do 22.01.04 15:22
hallo blackbird!
wenn dein programm beim einlesen der daten von CD abstürzt, dann wird es vermutlich fehlerhaft sein. eine mögliche ursache dafür wäre, dass versucht, auf der CD zu schreiben.
am einfachsten ist es, wenn du einen breakpoint am beginn der vergleichsroutine setzt und dann die zeilen zeilenweise abklapperst, bis du zu der zeile gelangst, an der die fehlermeldung auftaucht. sonst artet das ganze zu einer schnitzeljagd aus
überprüfst du eigentlich, ob eine CD im laufwerk liegt, oder liest du munter drauf los?
mfg, stefan
|
|
MaxiTB
      
Beiträge: 679
Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
|
Verfasst: Do 22.01.04 15:41
Es kommt drauf an, wie du die Daten liest.
Ich denke mal, daß du eine Runtime-Exception als Absturz bezeichnest. Das ist eine nicht abgefange Exception aus der Delphi Klassenbibliothek.
Ich hab leider nix hier zum Nachschlagen (Thema Streamklassen), daher gehe ich mal davon aus, daß du die einfache, klassische Variante benutzt:
Delphi-Quelltext 1: 2: 3:
| AssignFile(lHandle,'Blabblabla-was-für-ein-toller-Dateiname'); Reset(lHandle); CloseFile(lHandle); |
Ich hoffe, daß hab ich jetzt richtig aus dem Gedächnis. Auf jedenfall kannst du dann das hier machen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| {$I-} AssignFile(lHandle,'Blabblabla-was-für-ein-toller-Dateiname'); if IOError()>0 then begin end; Reset(lHandle); if IOError()>0 then begin end; CloseFile(lHandle); {$I+} |
So in etwa kannst du den fehlerhaften Zugriff abfangen.
Bei streams kommst um ein try ... except plus try ... finally nicht drum herum, ist aber schön, eleganter, moderner usw. 
_________________ Euer Mäxchen
Wer früher stirbt, ist länger tot.
|
|
Blackbird 
      
Beiträge: 54
|
Verfasst: Do 22.01.04 20:35
Erst mal danke für eure Antworten!
@grayfox:
Nein das Programm versucht net auf der CD zu schreiben - es wäre mir jedenfalls neu wenn das bei
Quelltext 1:
| F := TFilestream.create('BlaBlaDateiname.bla',fmopenread); |
passieren würde.
Desweitern überprüft das Programmm nicht ob eine CD im Laufwerk ist, was aber auch egal ist, da sich die CD 100%ig im Laufwerk befindet bzw. der Dateiname über einen OpenDialog ermittelt wird (sprich wenn die CD net drinliegen würde könnte ich die Datei auch nich auswählen)
@MaxiTB:
Ich benutze die Streamvariante aber ich habe auch deine Variante probiert. Das Problem tritt auf wenn ich versuche die Datei zu lesen (wir reden hier von einer Datei von der ich zu Probezwecken weiss, dass sie definitiv lesbar ist, also existiert).
Selbst eine Datei die Physisch korrekt ist kann ich also nich lesen, obwohl die CD im Laufwerk liegt.
Ich habe keine Ahnung wo hier das Problem liegt...
|
|
MaxiTB
      
Beiträge: 679
Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
|
Verfasst: Do 22.01.04 20:52
Hm ... vielleicht sollest du mal eine try ... except versuchen und dann den Fehler der Exception einfach in eine MessageBox ausgeben.
Wenn du das hast, weißt du mal wenigstens was passiert ist.
Wenns nix hilft, bleibt nur breakpoint und debuggen bis es duscht oder tuscht *g* Aber das kann eben ein bisserl mühseelig werden ...
_________________ Euer Mäxchen
Wer früher stirbt, ist länger tot.
|
|
Blackbird 
      
Beiträge: 54
|
Verfasst: Do 22.01.04 23:53
So jetzt habs ich hingekriegt das er wenigstens nicht defekte Dateien liest.
Nun zum eigentlichen Problem:
Wenn ich jetzt versuche (per Filestream) die defekte Datei einzulesen, dann tut er das bis das defekte Byte kommt. Ab dann geben das Programm und Delphi gar nix mehr von sich - nicht mal ne Exception oder so (die Read Methode ist natürlich von einem Try-Except Block umschlossen).
Wie kann ich dieses "Festfahren" verhindern ?
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Do 22.01.04 23:58
Nur mal so eine Frage, wie unterscheidet sich ein defektes Byte von einem heilen? Ist 10011011 jetzt heile oder defekt?  Den Filestream interessiert das Format der Datei herzlich wenig, da es die Daten nicht interpretiert. Also, was ist ein kaputtes Byte?
|
|
Blackbird 
      
Beiträge: 54
|
Verfasst: Fr 23.01.04 16:14
Mit defekt meine ich hier, dass die Daten von der CD nicht lesbar sind!
Das Programm hängt sich an dieseer Stelle komplett auf.
Wie gesagt, die Dateiinfos können ausgelesen werden, Fileexists liefert auch true zurück und einlesen geht auch bis zur kaputten stelle, dann passiert gar nix mehr.
|
|
MaxiTB
      
Beiträge: 679
Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
|
Verfasst: Fr 23.01.04 16:25
::blackbird
Ich will ja nicht lästern, aber es schaut so aus, daß nicht dein Programm sich aufhängt sondern wartet.
Und zwar auf eine Antwort des DeviceDrivers auf das nächste Byte ... das kommt aber nicht, wenn die CD defekt ist und nach einer gewissen timeout Zeit (bei einem CD-ROM so 60-120 Sekunden) kommt erst eine Exception ... vielleicht warst nur ein bisserl zu ungeduldig.
Ach ja - das timeout kann man leider nicht ändern; mich nervts auch immer wieder wenn Apps freezen (besonders der Explorer) wegen einer kaputten CD ...
_________________ Euer Mäxchen
Wer früher stirbt, ist länger tot.
|
|
Blackbird 
      
Beiträge: 54
|
Verfasst: Fr 23.01.04 16:46
Hmm mag sein das ich ein bischen ungeduldig bin...
Also hab ich jetzt einfach mal gewartet...
nach 1min: hm noch nix - naja gut warte ich eben noch eine
nach 2min: hmm immer noch nix, Geduld Geduld
nach 3min: hmmm jetz' könnt er aber langsam
nach 4min: ähm Zeit ist Geld - nach einem klick auf das "Schliessen" Button krieg ich ne "Das Programm reagiert nicht" Standart_windows Meldung...
Wenn ich jetzt die Datei versuche zu kopieren (auf Festplatte) mit dem Explorer dann dauerts ca 10Sec und ich krieg ne Fehlermeldung.
So in etwa wollt ich das auch haben mit meinem Programm...
|
|
MaxiTB
      
Beiträge: 679
Win2000, WinXp, Workbench ;-)
D7 Ent, VS2003 Arch.
|
Verfasst: Fr 23.01.04 16:53
Titel: ::blackbird
Dann hast so ein blödes CD-ROM wie meinen Brenner ... der tut endlos und die Sache freezed.
Nop - da kann man Windows keine Schuld geben, wie gesagt, der Treiber legt fest, wann er Windows mitteilt, daß die CD nicht gelesen werden kann. Solange aber ds Lamperl auf dem Laufwerk leuchtet, blink oder hat nicht ganz aus ist und sich die Scheibe dreht, kannst davon ausgehen, daß der Treiber immer noch versucht, auf das blöde Ding zuzugreifen.
Und warums beim Explorer schneller geht, weiß ich nicht ... im schlimmsten Fall muß eben API Funktionen zum Öffnen nehmen, vielleicht machen die Stream Klassen da noch Extrawürstchen oder eben Frankfurter, weil Wiener essen wir hier nicht 
_________________ Euer Mäxchen
Wer früher stirbt, ist länger tot.
|
|
KidPaddle
      
Beiträge: 351
WinXP,Linux
D7 Prof, XE7
|
Verfasst: Fr 23.01.04 17:04
Oder er greift durch einen Thread auf die Daten zu und bricht diesen nach einigen Sekunden ab.
Gruß
KidPaddle
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 23.01.04 21:17
Also geht es nicht um defekte Bytes, sondern defekte / beschädigte Datenträger. Das heißt die Daten kommen erst gar nicht bis zu deinem Programm. Da kannst du so viel tollem Source schreiben wie du willst, wenn der Treiber bzw.Windows dir die Daten nicht liefern, nützt das alles nichts.
Ich würde das so machen: Ich würde das Kopieren in einen Thread auslager (solltest du eigentlich schon gemacht haben), und mir aus dem Thread eine Nachricht an mein Fensterschicken lassen. Da mann sie auch mit einem Filesstream sinnvollerweise ein eeiner Schleife einliest (immer 4096 Bytes oder so), verschickst du diese Nachricht in der Schleifen. In deinem Fenster kuckst du nun immer wie viel Zeit zwischen den Nachrichten vergangen ist. Liegt dieser Wert über einer selbst definierten Grenze, beendets du den Thread und brichst so den Kopiervorgang ab.
Edit für die Mods: Warum sind Threads, bei denen es um Drucker geht in der Sparte "Dateizugriff" und Threads, bei denen es um Dateien geht in der Sparte "CLX / Delphi Language"?
|
|
|