Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.03.20;
Скачать: CL | DM;

Вниз

Чтение со сбойной дискеты   Найти похожие ветки 

 
Koster   (2003-01-23 16:00) [0]

Как грамотно реализовать чтение файла со сбойной дискеты?
Постановка задачи такая - прочитать файл с дискеты, при этом, возможно,
некоторые сектора повреждены (не читаются). Поврежденные участки прочитанного
файла следует запомнить для дальнейшего восстановления.

Собственно проблема такая - делаю чтение при помощи ReadFile
в режиме FILE_FLAG_OVERLAPPED, т.е. асинхронного чтения.
В программе ожидаю 2000 мс. наступления события либо если чтение не выполнено
прерываю чтение при помощи CancelIO()
Но вот проблема, если чтение достигло сбойного участка, вся программа зависает
и функция WaitForSingleObject не завершается через 2 секунды.
Пробовал делать чтение в отдельном потоке - то же самое.
Как же сделать правильно?

Вот код:

function Read_File(const fn: string; var filesize: DWORD; var data: TFile; var errordata: TBlockArray): Boolean;
var
h_File: HFILE;
s_filedata: OFSTRUCT;
err: DWORD;

buf: TBlock;
totalsize, current, current_read, block: DWORD;
s_overlapped: OVERLAPPED;
h_Event: THANDLE;
wait: DWORD;

begin
Result := False;
s_filedata.cBytes := sizeof(s_filedata);
h_File := OpenFile(PChar(fn), s_filedata, GENERIC_READ + FILE_FLAG_OVERLAPPED);
if h_file = HFILE_ERROR then Exit;
filesize := GetFileSize(h_File, nil);
if filesize = $FFFFFFFF then begin
err := GetLastError();
CloseHandle(h_file);
SetLastError(err);
Exit;
end;
h_Event := CreateEvent(nil, false, false, nil);
if h_Event = 0 then begin
err := GetLastError();
CloseHandle(h_file);
SetLastError(err);
Exit;
end;
SetLength(data, filesize div sizeof(TBlock) + 1);
SetLength(errordata, filesize div sizeof(TBlock) + 1);

totalsize := 0; block := 0;
while totalsize < filesize do begin
current := filesize - totalsize;
if current > sizeof(TBlock) then current := sizeof(TBlock);

// ========= Чтение:
s_overlapped.Internal := 0;
s_overlapped.InternalHigh := 0;
s_overlapped.Offset := totalsize;
s_overlapped.OffsetHigh := 0;
s_overlapped.hEvent := h_Event;
if ReadFile(h_File, buf, current, current_read, @s_overlapped) = false then begin
err := GetLastError();
CloseHandle(h_file);
CloseHandle(h_Event);
SetLastError(err);
Exit;
end;
wait := WaitForSingleObject(h_Event, 2000);
if wait = WAIT_OBJECT_0 then begin
data[block] := buf;
errordata[block] := true;
end else if wait = WAIT_TIMEOUT then begin { error }
CancelIO(h_File);
errordata[block] := false;
end;
// ==========

inc(totalsize, current);
inc(block);
end;
CloseHandle(h_File);
CloseHandle(h_Event);
end;



 
Sancho ©   (2003-01-23 22:13) [1]

А не легче ли делать резервное копирование нужных файлов?


 
Koster   (2003-01-24 09:55) [2]

Собственно это оно и есть, но если на двух копиях сбой (в разных местах) читать то как-то их надо. Хочу написать программу для автоматизации этой работы.


 
Reindeer Moss Eater   (2003-01-24 10:03) [3]

Koster, а если попробовать мыслить "ширше"?

Удельная стоимость хранения мегабайта на дискете это сколько?
А если еще и дубликаты иметь? А время на придумывание хитрых алгоритмов восстановления сколько стоит?

А если хранить данные на CD-R?



 
Слесарь Матерящийся ©   (2003-01-24 10:20) [4]

Зачем читать сбойную дискету? Не легче ли её выбросить...


 
Anatoly Podgoretsky ©   (2003-01-24 10:23) [5]

Хранить в сети на разных сайтах


 
Avsam ©   (2003-01-24 13:22) [6]

Я когда-то похожее делал.
Читаешь обычно с помошью BlockRead.
По 512 байтов.
Если при чтении очередного блока ошибка - запонимай номер блока и т.д.
Твоя задача довольно просто решается, не мудруй сильно.


 
Koster   (2003-01-24 20:51) [7]

>Avsam
Попробую, но с ReadFile прога долго пытается читать диск, прежде чем вернуть ошибку
>all
Прога для себя, а именно нужно таскать довольно много из зала с инетом домой :)


 
drnet   (2003-01-25 17:21) [8]

:) а для этого за $1 можно купить 80мм cd-rw, IMHO сколько на него поместится на дискетах не унесешь, еще и с дубликатом :)


 
Andreich   (2003-01-26 05:55) [9]

Вот, блин, советчики хреновы !!!
Ни одного ответа в тему.
Мыслить шырше, купить болванку,хранить в сети!!!
Был задан КАНКРЕТНЫЙ вопрос.
И ожидался не менее конкретный ответ.
А если не знаешь, так и не лезь.
Сиди и молчи в тряпочку.


 
Serious Sam   (2003-01-26 11:26) [10]

Но вообще-то, если в тему, ответ будет следующий:

Из серьёзных решений - 2 метода:
1. Многократное посекторное чтение с репозиционированием и анализом прочитанной информации на совпадения. Если на дорожке повреждены области синхронизации, это не поможет. Поэтому есть метод 2:
2. Чтение дорожки - всё содержимое сразу - поля синхронизации и данные. Затем анализ прочитанной информации.

К несчастью, ни один из этих методов нельзя реализовать через WinAPI. Только на уровне драйвера.



Страницы: 1 вся ветка

Текущий архив: 2003.03.20;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.02 c
14-64349
PrettyFly
2003-03-03 19:35
2003.03.20
Форум...


1-64076
Volly
2003-03-09 18:44
2003.03.20
Перетаскивание формы


7-64401
race1
2003-01-25 16:02
2003.03.20
keys


3-63942
AtoL
2003-03-03 15:26
2003.03.20
Программный backup БД


3-63956
Alander
2003-03-04 08:21
2003.03.20
Компонент abcDBTreeView