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.
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