Текущий архив: 2005.11.13;
Скачать: CL | DM;
Вниз
Копирование битых файлов. Найти похожие ветки
← →
Игорь Шевченко © (2005-10-13 23:32) [40]Virgo_Style © (13.10.05 23:27) [39]
> Так вот, нередко блок не читался, но побайтовое чтение проходило
> без ошибок.
Похоже, ты просто увеличивал количество повторов, устройство все равно читает блоками.
← →
dracula © (2005-10-17 15:51) [41]>Читал, кстати, старым добрым BlockRead. Может, потому так долго и получалось =))
Я тоже читаю BlockRead по 512 байт, меньше нет смысла, всёравно чтение происходит по секторам, и если сделать меньше 512 то просто мы увеличим количество обращений к этому сектору. А на счёт стоит это делать или нет, я думаю зависит от содержимого файла(битого), если это какойнибудь важный док или отчёт, то даже его часть может быть очень нужна.
- количество обращений мне всё равно надо контролировать, а пользователь уже сам будет решать сколько раз читать плохой сектор, пропускать его на лету, или читать до посинения =), у меня пока так и не получилось взять это под контроль, а надо =( Неужели в форуме нет людей кто сталкивался с этой проблемой, подтолкните в нужном направлении, а то совсем беда какая-то.
← →
dracula © (2005-10-25 13:51) [42]После долгих поисков и удалось выяснить, что в винде нельзя установить количество обращений к сектору =) но можно прервать его. Битые сектора надо обходить тайм аутами и использовать при этом OVERLAPPED.
var
hFile, hFileOut, hEvent : THandle;
ol : OVERLAPPED;
Returned : DWORD;
Buf : pointer;
size : integer;
ReadOK : boolean;
Sector : integer;
begin
size:=getfilesize(namein);//спец процедура :)
hFile := CreateFile(pchar("\\.\\"+namein), GENERIC_READ , FILE_SHARE_READ ,
nil,OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
hFileOut := CreateFile(pchar("\\.\\"+nameout), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE,
nil,CREATE_ALWAYS, FILE_ATTRIBUTE_archive, 0);
hEvent := CreateEvent(nil, False, False, nil);
FillChar (ol, SizeOf(ol), 0);
ol.hEvent := hEvent;
GetMem (Buf, 512);
Sector := 0;
while (Sector < ((size+511) div 512)) do
begin
ol.Offset := Sector * 512;
ol.OffsetHigh := 0;
ResetEvent(hEvent);
ReadFile (hFile, Buf^, 512, Returned, @ol);
ReadOK := (WaitForSingleObject(hEvent, 500) = WAIT_OBJECT_0);
if not ReadOK then CancelIo (hFile);
WriteFile (hFileOut, Buf^, 512, Returned, nil);
// файл получится больше, чем нужно, но с этим проблем нет:)
Inc (Sector);
end;
CloseHandle (hEvent);
CloseHandle (hFile);
CloseHandle (hFileOut);
FreeMem (Buf)
end;
Теперь моя проблема заключается в следующем, я раньше не работал с оверлеем, и чё то в моем исходнике криво, но понять не могу чего, если сектор читается больше 500 млс то CancelIO не срабатывает. Я пробовал открывать файл с флагамиFILE_ATTRIBUTE_NORMAL or
FILE_FLAG_OVERLAPPED or
FILE_FLAG_SEQUENTIAL_SCAN or
FILE_FLAG_NO_BUFFERING
но чё-то не догоняю? с этими флагами перестаёт сячитыватся в буфер. Хотя таймауты начинают работать. может кто подскажет решение.
← →
dracula © (2005-10-25 14:21) [43]Всё победил =) всётаки добился своего и теперь на лету пропускаю битые сектора, всё заработало просто забыл про GetOverlappedResult, оверлей через неё всё возвращает =).... всем спасибо за помощь.
← →
pasha_golub © (2005-10-25 18:52) [44]Ну, покаж код-то... Интересно все-таки :0)
Страницы: 1 2 вся ветка
Текущий архив: 2005.11.13;
Скачать: CL | DM;
Память: 0.54 MB
Время: 0.027 c