Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Копирование битых файлов.


Страницы:   1 2 3

dracula ©   (2005-09-29 14:14:00) 

Может кто подскажет... делаю копирование битого файла с дискеты, казалось бы всё просто читаем файл, нечитаемые сектора заменяем нолями, но как програмно это дело сделать? не знаю.  В каком направлении копать.. =( Может в винде есть флаги на установку количества раз чтения битого сектора, или чтоб вообще нафиг битые пропускал)... Если кто знает какю информацию по этому поводу помогите плз.


pasha_golub   (2005-10-25 18:52:00) [1]

Ну, покаж код-то... Интересно все-таки :0)


dracula   (2005-10-25 14:21:00) [2]

Всё победил =) всётаки добился своего и теперь на лету пропускаю битые сектора, всё заработало просто забыл про GetOverlappedResult, оверлей через неё всё возвращает =).... всем спасибо за помощь.


dracula   (2005-10-25 13:51:00) [3]

После долгих поисков и удалось выяснить, что в винде нельзя установить количество обращений к сектору =) но можно прервать его. Битые сектора надо обходить тайм аутами и использовать при этом 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-17 15:51:00) [4]

>Читал, кстати, старым добрым BlockRead. Может, потому так долго и получалось =))

Я тоже читаю BlockRead по 512 байт, меньше нет смысла, всёравно чтение происходит по секторам, и если сделать меньше 512 то просто мы увеличим количество обращений к этому сектору. А на счёт стоит это делать или нет, я думаю зависит от содержимого файла(битого), если это какойнибудь важный док или отчёт, то даже его часть может быть очень нужна.

- количество обращений мне всё равно надо контролировать, а пользователь уже сам будет решать сколько раз читать плохой сектор, пропускать его на лету, или читать до посинения =), у меня пока так и не получилось взять это под контроль, а надо =( Неужели в форуме нет людей кто сталкивался с этой проблемой, подтолкните в нужном направлении, а то совсем беда какая-то.


Игорь Шевченко   (2005-10-13 23:32:00) [5]

Virgo_Style ©   (13.10.05 23:27) [39]


> Так вот, нередко блок не читался, но побайтовое чтение проходило
> без ошибок.


Похоже, ты просто увеличивал количество повторов, устройство все равно читает блоками.


Virgo_Style   (2005-10-13 23:27:00) [6]

Игорь Шевченко ©   (13.10.05 22:32) [38]
Но долго, часа четыре.


Хм... Я уже не помню, сколько он у меня копировался. Я его на ночь оставлял. Раза два-три-четыре. :o)

Джо ©   (13.10.05 21:41) [37]
А зачем отказываться от дальнейшего чтения если не прочитался 1-й раз?


Кстати, меня заинтересовал такой момент (сразу скажу, что кривость рук не исключаю): я читал блоками (по сколько-то килобайт, уже не помню), а если блок не читался - пытался читать побайтово, от начала и от конца блока шел "внутрь", пытаясь спасти по возможности больше данных.
Так вот, нередко блок не читался, но побайтовое чтение проходило без ошибок.

Читал, кстати, старым добрым BlockRead. Может, потому так долго и получалось =))


Игорь Шевченко   (2005-10-13 22:32:00) [7]

Virgo_Style ©   (13.10.05 21:10) [36]

Я EAC-ом с поцарапанного пестню оцифровывал. Но долго, часа четыре. Оцифровал, в итоге, даже на слух без запинок :)


Джо   (2005-10-13 21:41:00) [8]

2Автор.
А зачем отказываться от дальнейшего чтения если не прочитался 1-й раз? Очень вероятно, что после 2-3 попыток все-же прочитается. Так зачем заведомо лишать себя шансов прочитать сектор, и записывать его сразу в "хлам".


Virgo_Style   (2005-10-13 21:10:00) [9]

Игорь Шевченко ©   (13.10.05 16:42) [35]
овчинка выделки не стоит - битые файлы копировать.


Я фильм с поцарапанного CD копировал :-) Хотя насчет стоимости выделки, пожалуй, согласен. Делать было нечего =)


Игорь Шевченко   (2005-10-13 16:42:00) [10]

dracula ©   (13.10.05 15:41) [34]

Я бы на твоем месте подождал и не мучился. Если учесть, что дискеты сейчас стали отвратные, то вообще овчинка выделки не стоит - битые файлы копировать.


dracula   (2005-10-13 15:41:00) [11]

> Могу посоветовать - не прочитался - сектор битый. И все.

В винде по умолчанию плохой сектор читается три раза, потом он считается плохим... Вот например копирую я файл, натыкаюсь на битый сектор и он читается три раза, если не прочитался пишу вместо него ноли в файл, читаю следующий сектор если битый то опять пишу ноли и т.д. это всё работает отлично, но очень долго... поэтому не пойдёт так просто, точнее пойдёт, но если читать битый сектор не три раза, а один - вот это то что мне нужно. Чтоб битый сектор читался один раз, так как и нормальный... ну не прочитался и фиг с ним, нолями забью. Простым языком говоря - просто пропускать плохие сектора на лету.


Игорь Шевченко   (2005-10-13 15:31:00) [12]

dracula ©   (13.10.05 14:55) [32]


> Неее... так не пойдёт. Совет может и хороший но не в тему
> =)


А почему не пойдет ?


dracula   (2005-10-13 14:55:00) [13]

Удалено модератором
Примечание: Личная переписка


Игорь Шевченко   (2005-10-13 13:53:00) [14]

dracula ©   (13.10.05 13:38) [28]

Могу посоветовать - не прочитался - сектор битый. И все.


Defunct   (2005-10-13 13:50:00) [15]

-=S..S=-   (12.10.05 17:48) [25]

Зато NTVDM пропускает обращения к INT 13h


Defunct   (2005-10-13 13:45:00) [16]

dracula ©   (13.10.05 13:38) [28]

хотите подкину программку посекторного копирования дискетки, на другую дискетку, где игнорируются все битые сектора (программка на TP7).


dracula   (2005-10-13 13:38:00) [17]

Игорь Шевченко ©

А можеш посоветуешь как проще? Вся проблема в том что мне надо получить контроль над количеством повтором чтения плохого сектора, и время между этими повторами.


Игорь Шевченко   (2005-10-13 12:42:00) [18]

dracula ©   (13.10.05 12:40) [26]

А зачем такие сложности ?


dracula   (2005-10-13 12:40:00) [19]

Я так думаю надо копать в направлении дров, всё должно быть просто (как в досе). Самое интересное и в MSDN нет ничего про это (или я искал плохо).


-=S..S=-   (2005-10-12 17:48:00) [20]

NT не пропускает 9x пропускает прямые вызовы к устройствам


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо