Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Система";
Текущий архив: 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
8-64233
brestmarket
2002-12-07 11:24
2003.03.20
Как определить максимально возможное значение уровня звука?


14-64378
HanIP
2003-03-05 19:34
2003.03.20
quickreport


1-64057
Новичек
2003-03-09 17:28
2003.03.20
Проектирование собственного диалога.


14-64308
igorr
2003-03-03 15:25
2003.03.20
Как пишется


1-64121
snake1977
2003-03-07 09:59
2003.03.20
FileListBox





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский