Bonjour,

Je dispose d'un cd dont je cherche à extraire les fichiers.
Malheureusement l'un de ces fichiers possède une zone avec des secteurs illisibles.

Comment puis-je copier ce fichier sachant que l'explorer de windows commence la copie, arrive sur la zone illisible, et plante.

J'ai essayé avec la fonction FileRead, du début à la fin du fichier, mais mon essai ne fut pas concluant.
cette fonction a le même problème que explorer.Exe, arrivée sur la zone illisible, le lecteur dvd tente de lire la zone à l'infinie. Seule solution : éjecter le cd et le remettre poru continuer la copie secteur par secteur (cette solution ne me convient pas).
J'ai essayé de mettre par la suite le code avec FileRead dans un thread (pour ne pas planter tout le système). Malheureusement le résultat est le même que précédemment.

Après quelque recherche, j'ai découvert dans l'api de windows, la fonction ReadFile, possédant une lecture asynchrone.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
type
  TBuffer = Array[0..2047] of Byte;
var
  Buffer : TBuffer;  // buffer utilisé pour la copie
  SrcHandle, DestHandle : THandle;  // handle
  Overlapped : POverlapped; 
  Pos : integer;  // position du curseur sur le fichier source en coursde lecture
  ReadSuccess : boolean; // indique si la lecture s'est bien déroulée
  ReadCount : integer;
 
 
SrcHandle := CreateFile('E:\missions.dat', GENERIC_READ, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED or FILE_FLAG_NO_BUFFERING, 0); // ouvre le fichier source
DestHandle := CreateFile('C:\temp\test.test', fmCreate or fmOpenWrite); // crée le fichier cible
 
Pos := 0;
FileSeek(SrcHandle, Pos, 0); // Se positionne au début du fichier source
 
New(Overlapped); // Création de la structure Overlapped
Overlapped.Offset :=0;
Overlapped.OffsetHigh := 0;
Overlapped.hEvent := 0;
 
ReadSuccess := ReadFile(SrcHandle, Buffer, 2048, ReadCount, Overlapped); // lecture
if not ReadSuccess then Begin // la lecture ne se déroule jamais correctement au 1er coup. on cherche la raison
  case GetLastError of
    ERROR_HANDLE_EOF :  // fin du fichier
    begin
      // placer code de fin
    end;
 
    ERROR_IO_PENDING :  // fichier en cours de lecture
    begin
      ReadSuccess := GetOverlappedResult(SrcHandle, Overlapped^, readCount, FALSE);  // teste si la lecture s'est bien déroulée.
      if ReadSuccess then Begin
        FileWrite(DestHandle, Buffer, 2048);  // écriture du buffer dans le fichier
      End;
    End;
  End;
End;
Le code ci-dessus marche très bien, mais pour la lecture des 2048 premiers octets du fichiers.
impossible de faire un fileseek (ou SetFilePointer) pour me déplacer dessus, je lis toujours les mêmes 2048 premiers octets du fichier.

Si quelqu'un a une piste pour m'aider, car je ne maitrise vraiment pas la lecture asynchrone.
Merci

Bertrand