Прогулка по файловой системе - часть 6
if (-d $name){ ft это каталог?
&ScanDirectory($name); next; } unless (&CheckFile($name)){
print &cwd."/".$name."\n"; # выводим имя
ft поврежденного файла } }
sub CheckFile<
my($name) = shift;
print STDERR "Проверяется ". &cwd."/'".
$name. "\n"; # пытаемся получить состояние файла my @stat = stat($name);
if (!$stat[4] && '$stat[5] && !$stat[6] && !$stat[7] && l$stat[8]){ return 0;
i )
# пытаемся открыть этот файл unless (open(T,"$name")){
return 0: }
tt читаем файл по байту за один раз for (my $i=0;$i< $stat[7]:$i++){
фу $r=sys'-ead(T.$i, 1);
if ($r '= 1) { dose(T); retu--n 0 } >
close(T);
return 1: >
&ScanDirecto-y("."):
Различия между этой программой и последним примером заключаются в наличии дополнительной подпрограммы для проверки каждого найденного файла. Для каждого файла мы вызываем функцию stat, чтобы проверить, можно ли прочитать информацию о файле (например, его размер). Если мы сделать этого не можем, значит, файл поврежден. Если же прочитать эту информацию можно, мы предпринимаем попытку открыть файл. А в качестве последней проверки пытаемся прочитать каждый байт из файла. Это не гарантирует, что файл не поврежден (его содержимое могло измениться), но это говорит о том, что файл можно прочитать.
Вы можете удивиться, зачем применять такую странную функцию, как sysread(), для чтения файла, если можно применить о или г ead (), обычно используемые для этого в Perl. Дело в том, что sysread() позволяет читать файл побайтно, не применяя обычную буферизацию. Если файл поврежден в позиции X, нет смысла ждать, пока будут прочитаны байты в позициях Х+1, Х+2, Х+3 и т. д., как это бывает при обращении к обычным библиотечным функциям. Мы хотим, чтобы попытки читать файл в таком случае прекратились немедленно. Обычно файл читается по кускам в целях повышения производительности, но это нежелательно, т. к. в нашем случае компьютер будет издавать ужасающие звуки в течение длительного времени, когда наткнется на поврежденный файл.
Теперь, после рассмотрения использованной мною программы, я расскажу, чем закончилась эта история. После того как рассмотренный сценарий проработал всю ночь (без преувеличений), он нашел 95 поврежденных файлов из 16000. К счастью, ни один из них не был файлом из книги, которую вы сейчас читаете; я снял копии со всех хороших файлов и перенес их в другое место. Perl просто спас положение.