Форум: "Система";
Текущий архив: 2003.03.20;
Скачать: [xml.tar.bz2];
ВнизЧтение со сбойной дискеты Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.007 c