Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Klatsch und Tratsch (https://www.delphipraxis.net/34-klatsch-und-tratsch/)
-   -   Beschädigte Datei retten ? (https://www.delphipraxis.net/161717-beschaedigte-datei-retten.html)

Cicaro 17. Jul 2011 12:36

Beschädigte Datei retten ?
 
Hallo.

Weiß jemand, wie man am besten 1 Datei kopieren kann, bei dem Windows einen E/A Gerätefehler meldet ?
Es ist ein Video File *.avi und ich habs schon mit VirtualDub angesehen. Es sind vorne, hinten, in der Mitte Frames, die noch in Takt sind (möglicherweise nur ein paar Cluster unlesbar). Ich möchte die Datei kopieren und die fehlerhaften Cluster mit Nullen ausfüllt haben. "Dust Signs File Copier" läuft gerade und ist steckengeblieben. Ich fürchte es wird scheitern. Kennt noch wer was Funktionierendes ?

/edit/ Es ist eine 4 GB Datei (mit Fraps erstelt) und liegt auf einer externen Festplatte.

MfG

himitsu 17. Jul 2011 12:38

AW: Beschädigte Datei retten ?
 
Irgendwo hab ich eventuell noch ein altes fehlerüberspringendes Kopierprogramm rumliegen (mal sehn ob ich's finde).

Worauf befindet sich denn diese Datei? (CD/DVD oder HDD ... bei letzerem Checkdisk drüberlaufen lassen)

Christian Seehase 17. Jul 2011 13:36

AW: Beschädigte Datei retten ?
 
Moin Cicaro,

schau mal im Eventviewer, ob dort eventuell Plattenfehler gemeldet werden.

WM_CLOSE 17. Jul 2011 14:31

AW: Beschädigte Datei retten ?
 
Kann es vielleicht sein, dass die Datei von einem anderen Rechner als deinem auf die Platte kopiert wurde? ODer dass die Platte FAT(32) formatiert ist?
FAT kann mit Dateien>4GB nicht umgehen, da braucht es schon NTFS.

himitsu 17. Jul 2011 15:33

AW: Beschädigte Datei retten ?
 
Nee, find es nicht mehr, aber hier mal eine ganz einfache Konstruktion:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  i, o: TStream;
  p, l: Int64;
  b: array[0..511] of Byte;
begin
  o := nil;
  i := TFileStream.Create(Edit1.Text, fmOpenRead or fmShareDenyNone);
  try
    o := TFileStream.Create(Edit2.Text, fmCreate);
    l := i.Size;
    p := 0;
    while p < l do
      try
        i.Position := p;
        o.Position := p;
        o.Write(b, i.Read(b, SizeOf(b)));
        Inc(p, SizeOf(b));
      except
        Inc(p, SizeOf(b));
      end;
  finally
    o.Free;
    i.Free;
  end;
end;
Für CD/DVD kann/sollte man aus dem 511 ein 2047 machen (es geht aber auch so, nur eben bis zu 4 Mal langsamer, bei den fehlerhaften Sektoren, aber immernoch schneller, als der Unstoppable :angle2: ).

Alternativ gibt es auch noch den Bei Google suchenUnstoppable Copier, aber ganz im Ernst, das Programm funktioniert zwar, ist allerdings total schrottig und scheinbar ohne das geringste Wissen über Dateizugriffe programmiert wurden und demnach extrem lahm.
(Byteweiser Zugriff, wo die Laufwerke doch nur Sektorweise arbeiten :wall: ... Seit ich weiß, wie das im Inneren arbeitet, kann ich das Teil eigentlich nicht mehr wirklich empfehlen)



Kannst'e ja mit 2 TEdits und einem TButton zum Laufen bekommen (eventuell auch noch je ein TButton mit TOpenDialog, bzw. TSaveDialog an die Edits dran)
oder direkt die Dateinamen/-pfade angeben.

Cicaro 17. Jul 2011 15:44

AW: Beschädigte Datei retten ?
 
Jain, beide Systeme sind NTFS. Ich wollte die Datei mithile einer externen Festplatte von einem PC auf nen anderen kopieren und es ist wohl auf schlechten Sektoren gelandet. Ich hab jetzt meine Datei mit VirtualDub in 2 Teile aufgeteilt und habe 35 unlesbare Frames verloren. Ich kanns verschmerzen. Aber das Problem ist hier nicht wirklich gelöst. Wie rettet man Nicht-VirtualDub-Kompatible-Dateien ?

Ich hab "Dust Sign File Copier" und "unstopcp" ausprobiert. Beide blieben bei der Stelle mit fehlerhaften Clustern hängen (hab sie abgebrochen, vielleicht funktionieren sie ja doch noch, aber es dauerte mir zu lange).

Cicaro 17. Jul 2011 15:50

AW: Beschädigte Datei retten ?
 
Zitat:

Zitat von himitsu (Beitrag 1112264)
Nee, find es nicht mehr, aber hier mal eine ganz einfache Konstruktion:
...

Hab mir auch schon überlegt, mir in Delphi nen "Kopierer" zu programmieren. Aber mit VirtualDub gibgs schneller ^^ (hm mal testen, ob der Code funktioniert. Wenn Delphi "meinen" Fehler auch als Exception abfängt, sollte es eigentlich)

himitsu 17. Jul 2011 16:02

AW: Beschädigte Datei retten ?
 
Nja, es werden nicht alle Fehler als Exception zurückgemeldet.

Einige sagen nur 0, bzw -1 oder "weniger als man lesen wollte" ("0 Byte verarbeitet", bzw. INVALID_FILE_irgendwas oder "konnte nicht alles verarbeiten")
und geben zusätzlich einen Fehlercode (GetLastError) zurück.
TFileStream.Read wertet diese Fehlermeldungen allerdings nicht aus (im Gegensatz zu TFileStream.ReadBuffer), womit an solchen Stellen nichts geschrieben wird.
In Windows NT-Systemen werden unbeschriebene Teile einer Datei automatisch mit Nullen gefüllt.



Wie gesagt, ist ein sehr einfacher Code.
Richtiger/Besser wäre es, wenn sich das Ganze selber an die Sektorgröße der Datenträger anpaßt, wenn man eventuell noch die WindowsFileCache umgeht und wenn man noch die eine oder andere Fehlermeldung des Systems (von Windows) deaktivert.

Cicaro 18. Jul 2011 22:09

AW: Beschädigte Datei retten ?
 
Also dein Code funktioniert nicht. Bleibt in etwa an der Fehlerstelle stecken und reagiert nicht mehr. Man sollte wohl noch näher an WinAPI programmieren oder mir Assembler ran. Aber ich hab da gerade keine Lust drauf, da ich die beschädigte Datei bereits entfernt habe und nicht mehr testen kann.

himitsu 19. Jul 2011 08:21

AW: Beschädigte Datei retten ?
 
Tja, dann hast du ein kleines Problemchen ... scheinbar stürtzt de Treiber dort ab, bzw. bleibt hängen, und wenn die Leseoperationen nicht zurückkommen, dann war's das.

Welches Windowsversion nutzt du denn,
wie reagieren die Programme, wenn man sie beenden will? (lassen sie sich "leicht" über [X] oder den Taskmanager beenden)

Wie gesagt, das ist ein sehr ein einfacher Code und ein/zwei Ecken gibt es noch, wo man was drehen kann, aber ob man so am Treiber vorbei kommt...
Darum die Frage nach dem Beendeverhalten des Programms ... also ob es sich lohnt das jetzt noch "schnell" umzuschreiben und es dann nochmal zu versuchen.

DelphiSecurity 19. Jul 2011 08:31

AW: Beschädigte Datei retten ?
 
HIER KLICKEN, IST DAS BESTE

himitsu 19. Jul 2011 08:45

AW: Beschädigte Datei retten ?
 
Bekommst du eine Provision, oder warum diese Schrift?

Es wurde schon genannt und wenn ich es richtig verstanden hab, dann wurde es schon erfolglos ausprobiert.

Außerdem: Das Teil ist schlecht programmiert und funktioniert bei Weitem nicht so gut, wie überall angepriesen. (Gründe hatte ich schon genannt)
Ja, ich hatte auch schon defekte CDs und bin über dieses Programm gestolpert. :wall:

Luckie 19. Jul 2011 09:31

AW: Beschädigte Datei retten ?
 
Wie willst du an dem Treiber vorbeikommen? Der Treiber ist die einzige Schnittstelle zur Hardware.

himitsu 19. Jul 2011 09:56

AW: Beschädigte Datei retten ?
 
Nja, über Overlapptoperationen und mit Threads kann man versuchen eine Art Timeout für die Leseoperation einzubauen und so das Hängenbleiben zu umgehen.

Luckie 19. Jul 2011 10:13

AW: Beschädigte Datei retten ?
 
Dann hast du dich aber falsch ausgedrückt. Denn ohne Treiber keinen Zugriff auf die Hardware.

himitsu 20. Jul 2011 02:44

AW: Beschädigte Datei retten ?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Was hat Checkdisk nun eigentlich zu deiner Festplatte gesagt?


AsyncIO ist noch nicht richtig implementiert, die Threadbehandlung ist sehr disoptimal und beim Einlesen von intakten Sektoren könnte man über eine halbwegs "intelligente" Verwaltung noch so einiges zusammenfassen/beschleunigen.
Keine Ahnung, ob es schon reicht, um den hängenden Leseprozess zu umgehen.


Delphi-Quellcode:
procedure ShowError(ErrorMessage: String);
var
  E: HRESULT;
begin
  E := GetLastError;
  raise Exception.Create(ErrorMessage + ':' + sLineBreak + SysErrorMessage(E));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i, O: THandle;
  P, L: Int64;
  S, X, C, W, V: LongWord;
  T: TOverlapped;
  B: array of Byte;
  Q: LongInt;
begin
  if not GetDiskFreeSpace(PChar(ExtractFileDir(ButtonedEdit1.Text)), X, S, X, X) then S := 4096;
  i := INVALID_HANDLE_VALUE;
  O := INVALID_HANDLE_VALUE;
  try
    i := CreateFile(PChar(ButtonedEdit1.Text), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING,
      FILE_ATTRIBUTE_NORMAL or FILE_FLAG_NO_BUFFERING or FILE_FLAG_OVERLAPPED or FILE_FLAG_SEQUENTIAL_SCAN, 0);
    if i = INVALID_HANDLE_VALUE then ShowError('Kann Quelldatei nicht öffnen');
    O := CreateFile(PChar(ButtonedEdit2.Text), GENERIC_WRITE, FILE_SHARE_READ, nil, CREATE_ALWAYS,
      FILE_ATTRIBUTE_NORMAL or FILE_FLAG_NO_BUFFERING or FILE_FLAG_SEQUENTIAL_SCAN, 0);
    if O = INVALID_HANDLE_VALUE then ShowError('Kann Zieldatei nicht öffnen');
    Int64Rec(L).Lo := GetFileSize(i, @Int64Rec(L).Hi);
    if L = INVALID_FILE_SIZE then ShowError('Dateigröße nicht lesbar');
    SetLength(B, S);
    V := GetTickCount;
    P := 0;
    while (P < L) and not Application.Terminated do
      try
        if GetTickCount - V > 150 then begin
          Label2.Caption := Format('%.0n / %.0n', [P / 1, L / 1]);
          ProgressBar1.Position := (P * 1000) div L;
          Application.ProcessMessages;
          V := GetTickCount;
        end;
        if CheckBox1.Checked then begin
          T.InternalHigh := 0;  // reset OverlappedResult
          T.InternalHigh := 0;  //
          T.Offset    := Int64Rec(P).Lo;
          T.OffsetHigh := Int64Rec(P).Hi;
          Q := 0;
          TSimpleThread.Create(procedure
            begin
              try
                ReadFile(i, B[0], S, X, @T);
                if not GetOverlappedResult(i, T, C, True) or (C <> S) Then ShowError('Lesefehler');
                InterlockedExchange(Q, 1);
              except
                InterlockedExchange(Q, 2);
                raise;
              end;
            end);
          W := GetTickCount;
          while (Q < 1) and (GetTickCount - W < 15000) do begin
            Application.ProcessMessages;
            Sleep(10);
          end;
          if Q = 0 then begin
            TSimpleThread.Create(procedure
              begin
                try
                  CancelIoEx(i, T);
                  InterlockedExchange(Q, 3);
                except
                  InterlockedExchange(Q, 4);
                  raise;
                end;
              end);
            W := GetTickCount;
            while (Q < 3) and (GetTickCount - W < 500) do begin
              Application.ProcessMessages;
              Sleep(10);
            end;
          end else if Q <> 1 then Exit;
        end else begin
          T.InternalHigh := 0;  // reset OverlappedResult
          T.InternalHigh := 0;  //
          T.Offset    := Int64Rec(P).Lo;
          T.OffsetHigh := Int64Rec(P).Hi;
          ReadFile(i, B[0], S, X, @T);
          if not GetOverlappedResult(i, T, C, True) or (C <> S) Then ShowError('Lesefehler');
        end;
        X := Int64Rec(P).Hi;
        if (SetFilePointer(O, Int64Rec(P).Lo, @X, FILE_BEGIN) <> Int64Rec(P).Lo) or (X <> Int64Rec(P).Hi) then
          ShowError('Positionsfehler');
        X := Min(L - P, S);
        if not WriteFile(O, B[0], X, C, nil) or (C <> X) then ShowError('Schreibfehler');
        Inc(P, S);
      except
        Inc(P, S);
      end;
  finally
    CloseHandle(O);
    CloseHandle(i);
    CloseHandle(T.hEvent);
  end;
end;
Die Edits sollten eine Autovervollständigung (beim Schreiben), Drag&Drop und Dateiauswahldialoge bieten.

FredlFesl 20. Jul 2011 05:40

AW: Beschädigte Datei retten ?
 
Nur mal so: Wieso bimmeln hier keine Alarmglocken?
Ich meine "große AVI-Datei"? Kopierproblem?

Kann man nicht mal klären, was in der AVI-Datei so drin ist?
Darf der Threadersteller das überhaupt *kopieren*? Gibts da nicht sowas wie Copyright und so?

Sind die Fragen geklärt oder ich zu paranoid?

himitsu 20. Jul 2011 08:18

AW: Beschädigte Datei retten ?
 
Keine Sorge, mein Code umgeht keinen Kopierschutz, wie z.B. CSS und Co. (welcher eh schon lange geknackt ist und sich mit entsprechenden Programmen leichter entschlüsseln ließe).

PS: Besagte DVD-Dateien wären maximal auch nur 2 GB und nicht 4.

Medium 20. Jul 2011 09:29

AW: Beschädigte Datei retten ?
 
Zitat:

Zitat von FredlFesl (Beitrag 1112651)
Sind die Fragen geklärt oder ich zu paranoid?

Letzteres. Noch nie ein Urlaubsvideo vom Digi-Camcorder am PC geschnitten, was? ;) Allein aus "ich habe ein 4GiB Video" gleich einen Verdacht zu konstruieren finde ich reichlich anmaßend.

p80286 20. Jul 2011 10:52

AW: Beschädigte Datei retten ?
 
Ich habe auch schon mal defekte DVDs oder CDs auslesen müssen, da funktionierte der code aus #5 allerdings.
(Gut ich hatte einen Buffer dazwischen gepackt und massig Zeit)

Gruß
K-H

OldGrumpy 20. Jul 2011 17:12

AW: Beschädigte Datei retten ?
 
Der große Knackpunkt bei der Sache hier ist der unscheinbare Hinweis auf die externe Festplatte. Viele USB-IDE/SATA-Bridges kommen mit defekten Sektoren überhaupt nicht zurecht und spielen dann toter Mann - der Datentransfer bleibt hängen und manchmal hilft sogar nur noch, den USB-Stecker zu ziehen.

Daher immer die Festplatte aus dem externen Gehäuse raus und direkt ans Mainboard anhängen - schon geht das Auslesen selbst an den defekten Stellen weiter, wenn auch erst nach einigem Gerödel und ggf. etwas Wartezeit. Übrigens funktioniert dann auch der Code aus (WIMRE) #5.

p80286 20. Jul 2011 17:47

AW: Beschädigte Datei retten ?
 
[OT] Wenigstens einer hier der lesen kann [/OT]

himitsu 20. Jul 2011 21:02

AW: Beschädigte Datei retten ?
 
Zitat:

Zitat von OldGrumpy (Beitrag 1112759)
Der große Knackpunkt bei der Sache hier ist der unscheinbare Hinweis auf die externe Festplatte. Viele USB-IDE/SATA-Bridges kommen mit defekten Sektoren überhaupt nicht zurecht und spielen dann toter Mann - der Datentransfer bleibt hängen und manchmal hilft sogar nur noch, den USB-Stecker zu ziehen.

Darum ja auch die Frage nach den Programmverhalten.
Selbst wenn ein Lesevorgang verreckt müssen nicht alle stehenbleiben und wenn letzeres zutrifft, dann gibt es auch Möglichkeiten da etwas zu machen, ohne an der Hardware rumzuspielen.

Aber dafür müßte man erstmal erfahren was passiert.
- Lassen sich hängengebliebene Programme beenden und wenn ja wie?
- Welches Betriebssystem läuft? (mein letzer Code benötigt z.B. mindestens Windows Vista)
- Können andere Programme noch auf den Datenträger oder gar die Datei zugreifen, wärend ein anderes Programm hängt?
- ...

OldGrumpy 20. Jul 2011 21:39

AW: Beschädigte Datei retten ?
 
Das übliche Verhalten (sprich bei allen ca. 10 Bridge-Chips die mir unterkamen bis auf einen kombinierten USB/IEEE1394-Chip von WIMRE Cypress der sich robuster verhielt) ist simpel: Egal ob unter Linux oder Windows (bis 7 gleiches Verhalten) spielen die Chips einfach toter Mann. Zugriffe aufs Device werden nicht mehr beantwortet, Trace durch den I/O-Stack zeigt, dass die Datenpakete sogar bis zum Chip durchgereicht werden, es erfolgt aber nie mehr eine Antwort mit z.B. dem angeforderten Sektor oder einem Fehlercode. Auslöser ist in allen Fällen ein defekter Sektor mit dem die Platte sehr lange beschäftigt ist. Offenbar gibts da ein chipinternes Timeout was dann alles ins Chaos stürzt.

FredlFesl 21. Jul 2011 06:21

AW: Beschädigte Datei retten ?
 
Zitat:

Zitat von Medium (Beitrag 1112681)
Zitat:

Zitat von FredlFesl (Beitrag 1112651)
Sind die Fragen geklärt oder ich zu paranoid?

Letzteres. Noch nie ein Urlaubsvideo vom Digi-Camcorder am PC geschnitten, was? ;) Allein aus "ich habe ein 4GiB Video" gleich einen Verdacht zu konstruieren finde ich reichlich anmaßend.

"Anmaßend" ist hier anmaßend. Fragen wird man ja wohl noch dürfen und mein Keywort-Verdachts-Generator hat bei "AVI", "Kopieren", "Probleme" nun mal geblinkt. Probleme damit?

Übrigens habe ich keine Urlaubsvideos und ich finde in den Beiträgen hier auch sonst keinen Verweis. Aber möglich ist alles.

himitsu 21. Jul 2011 08:16

AW: Beschädigte Datei retten ?
 
Nja, mal sehn. ob der TE sich nochmal maldet und was er/sie dazu sagt.


Ansonsten: DVD = standardmäßig MPEG2

ToFaceTeKilla 21. Jul 2011 08:49

AW: Beschädigte Datei retten ?
 
Zitat:

Zitat von FredlFesl (Beitrag 1112651)
Nur mal so: Wieso bimmeln hier keine Alarmglocken?
Ich meine "große AVI-Datei"? Kopierproblem?

Kann man nicht mal klären, was in der AVI-Datei so drin ist?
Darf der Threadersteller das überhaupt *kopieren*? Gibts da nicht sowas wie Copyright und so?

Sind die Fragen geklärt oder ich zu paranoid?

Siehe Ausgangspost:

Zitat:

Zitat von Cicaro (Beitrag 1112212)
/edit/ Es ist eine 4 GB Datei (mit Fraps erstelt) und liegt auf einer externen Festplatte.

(Link von mir eingefügt)
Schonmal damit gearbeitet? Da haste ruckzuck eine Videodatei von beachtlicher Größe erstellt.

OldGrumpy 21. Jul 2011 09:14

AW: Beschädigte Datei retten ?
 
Zitat:

Zitat von FredlFesl (Beitrag 1112651)
Nur mal so: Wieso bimmeln hier keine Alarmglocken?

Ich hör da nur das Philisterglöckchen bimmeln ;)

Cicaro 29. Jul 2011 19:20

AW: Beschädigte Datei retten ?
 
Zitat:

Zitat von himitsu (Beitrag 1112213)
Tja, dann hast du ein kleines Problemchen ... scheinbar stürtzt de Treiber dort ab, bzw. bleibt hängen, und wenn die Leseoperationen nicht zurückkommen, dann war's das.

Welches Windowsversion nutzt du denn,
wie reagieren die Programme, wenn man sie beenden will? (lassen sie sich "leicht" über [X] oder den Taskmanager beenden)

Wie gesagt, das ist ein sehr ein einfacher Code und ein/zwei Ecken gibt es noch, wo man was drehen kann, aber ob man so am Treiber vorbei kommt...
Darum die Frage nach dem Beendeverhalten des Programms ... also ob es sich lohnt das jetzt noch "schnell" umzuschreiben und es dann nochmal zu versuchen.

Ich sag mal so viel, dass der Kopiervorgang NICHT schnell beendet werden kann. Windows hat ja selber Probleme die Datei zu kopieren und meldet den Fehler erst nach langer Wartezeit. Wenn du den Code ändern willst, schau dass du Fehler schneller ignorierend übergehen kannst. Am besten gleich GetLastError ohne Exceptions usw. Aber da verlässt du dich immer noch auf WinAPI. Also könnte auch das nichts bringen. Leider musst du dir irgendwo anders fehlerhafte Sektoren suchen. Meine Datei ist schon weg und ich weiß, wie ich meinem Problem in Zukunft aus dem Weg gehen kann (zumindest funktioniert es noch).

hathor 29. Jul 2011 19:57

AW: Beschädigte Datei retten ?
 
Mal was Grundsätzliches:

- wenn man Probleme mit Media-Files hat, muss man mit regsvr32 /u shmedia.dll
die Vorschaufunktion ausschalten, denn die blockiert bei einem fehlerhaften AVI-File
den ganzen Computer mit 100%-CPU-Last!
- die AVI-Frames (Index) müssen neu geschrieben/ neu nummeriert werden mit z.B. avifixed
- erst dann sollte man einen Kopierversuch machen

himitsu 29. Jul 2011 20:21

AW: Beschädigte Datei retten ?
 
Wenn man eh binär kopiert, ist der Index da nicht wirklich wichtig. (OK, das mit der DLL wäre bestimmt nicht schlecht, wobei sich auch noch andere Player dort einklinken)
Warum dann nivht zuerst kopieren und dann Index und Co. reparieren?
Bei Lesefehlern geht eh noch mehr "kaputt" und man könnte dann nochmal reparieren, außerdem dürfte das reparieren doch massig Probleme bekommen, wenn es auf die defekten Sektoren trifft. (nach'm Kopieren sind die Daten zwar immernoch kaputt, aber der Sektor isr wenigstens ganz)


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:56 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz