Программирование на perl — работа с бинарными файлами
— STDOUT – стандартный вывод;
— STDERR – стандартный вывод ошибок.
Внимание!Дескрипторы всегда записываются ПРОПИСНЫМИ буквами.
Они открываются автоматически для файлов и устройств.
Для открытия других – функция open, которые объединяют две функции в Pascal assign и open.
open (ДЕСКРИПТОР, "имя");
где ДЕСКРИПТОР – новый дескриптор файла.
имя — имя файла или устройства, что связывается с
дескриптором.
Это синтаксис открытия для чтения.
Для записи надо
">имя"
Для добавления
">>имя"
Для чтения и записи
"+<имя"
Функция open возвращает:
— true для успешного открытия;
— false в случае неудачи. Для чтения это в случае, если нет файла или к нему запрещен доступ. Для вывода – если файл защищен или нет доступа к каталогу ( или невозможна запись в каталог).
Для закрытия – close (ДЕСКРИПТОР).
При повторном открытии дескриптора файла автоматически закрывается ранее открытый файл.
Неудачное открытие (это, если не устанавливать признак или опцию — w):
— при чтении сразу "Конец файла";
— при записи – все пропадет.
Для сообщения – функция die – на стандартный вывод и завершает Perl-программу или процесс.
Пример:
open (LOG,">>logfile")||die("cannot open and append $!");
|| — логическое "или". die выполняется тогда, если open возвращает "false".
Всю запись можно читать как следующее:
"Открыть файл или умереть". Это поможет правильно поставить логическую операцию – "или" и "и".
Переменная $! содержит строку с описанием последней ошибки OS (к сообщению добавляется имя Perl-программы и номер строки, где стоит функция die). Если Вы не хотите указывать в сообщении имя файла и номер строки, то в конце сообщения у функции die нужно поставить исмвол новой строки "n".
Функция warn делает то же самое, что и die, только "не умирает".
После открытия файлов дескрипторы можно использовать.
Пример. Копирование файла 1 в файл 2.
open (IN,$a)||die ("can’t open for read $a.$!");
# Имя файла1 находится в переменной $a, в имя файла2 – в $b.
open (OUT,$b)||die ("can’t create $b.$!");
while (<IN>)
# При чтении дескриптор аомещается в угловые скобки, а дальше – # как при использовании стандартного ввода STDIN.
{ print OUT $_; # вывод строки в файл $b
print STDOUT; # вывод строки на стандартный вывод, то
# есть на экран монитора
}
close (IN)||die ("can’t close $a.$!");
close (OUT)||die ("can’t close $b.$!");
При записи дескриптор ставится сразу после слова print, перед остальными аргументами. Запятой между декриптором и остальными аргументами не должно быть.
Работа с бинарными файлами
Для чтения таких файлов применяется функция
sysread (ДЕСКРИПТОР,$string, число;
Для записи:
syswrite (ДЕСКРИПТОР,$string, число;
Эти функции читают и пишут блок указанного размера из файла, заданного дескриптором ДЕСКРИПТОР в скалярную переменную $string.
Для операционной системы UNIX нет разницы между бинарными и текстовыми файлами. Поэтому можно читать бинарный файл как текстовый, то-есть читать построчно до символа новой строки "n"). И наоборот, можно читать текстовый файл как бинарный, то-есть читать блоками байтов.
Для операционой системы Windows в этом есть разница. Чтобы указать, что используется бинарный файлы, необходимо применить функцию binmode (ДЕСКРИПТОР), иначе будет преобразование данных. Без функции binmode() в бинарном файле перед символом конец строки "n" появится символ возврат каретки "r".
Так как функция binmode() в ОС ничего не делает, то лучше всег вставлять эту фукцию всегда, если Вы работаете с бинарными файлами. Меньше будет забот при переносе программы с UNIX в Windows.
Операции для проверки файлов
-r файл или каталог доступен для чтения;
-w файл или каталог доступен для записи;
-x файл или каталог доступен для выполнения;
-e файл или каталог существует;
-z файл существует и имеет нулевой размер;
-s файл или каталог существует и имеет ненулевой размер (в
байтах);
-f элемент – обычный файл;
-d элемент – каталог;
-T файл – текстовый;
-B файл – двоичный;
-М время с последнего изменения в днях;
-A время с последнего доступа в днях.
Существуют и другие операции. Большинство возвращает "true" или "false".
Операция –s возвращает "true" и размер файла в байтах не равного нулю.
Операции –М –А – выдают "true" в днях ( десятичное число с точностью до одной секунды). Если при отборе файла будет выполнено сравнение с целым числом, например, с 3, то Вы получите только те файлы, которые были изменены ровно три дня назад, ни секундой раньше и ни секундой позже.
Пример. Проверка файла на чтение и запись.
print "Введите имя файла";
$f_n=<STDIN>;
chomp $f_n;
if (-r $f_n && — w $f_n)
{ …………………………
# файл $f_n, из него можно читать и в него можно записывать.
}
Эти операции могут работать и с дескрипторами
Оператор if (-x SOMEFILE) – проверяется на выполнение файл, открытый как SOMEFILE. Если имя или дескриптор файла не указаны, то-есть даны только операции –r или –s, то по умолчанию в качестве опереанда берется файл, указанный в переменной $_.
Пример:
print "$_ is readable" if –r;
if –r эквивалентно –r $_.
Для проверки многих других атрибутов файла применяется функция stat. Операнд функции stat – дескриптор файла или выражение, определяющее имя файла.
Возвращается значение undef – если вызов неудачен, 13-элементный список – иначе.
($dev, $ino, $mode,$nlink, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat (…);
dev – номер устройства файловой системы;
ino – номер индексного дескриптора;
mode – права доступа (номер жесткой ссылки на файл);
nlink – количество ссылок;
uid – идентиикатор пользователя;
gig – идентиикатор группы;
rdev – идентиикатор устройства, спецефичный только для файлов;
size – размер файла или каталога в байтах;
atime – время последнего доступа;
mtime – время последнего изменения;
ctime – время последнего изменения индексного дескриптора;
blksize – предпочтительный размер блока для файловой системы
I/O;
blocks – количество блоков в файле.
Пример:
Получить информацию об идентификаторе пользователя и группы из файла паролей.
($uid, $gid)= stat ("/etc/passwd")[4,5];
Мы здесь применили срез, то-есть извлечение пятого и шестого элементов списка.
Удаление файла
Для этого функция unlink. У файла может быть несколько имен. Когда удаляется последнее имя, то файл тоже удаляется. В большинстве случаев у файла одно имя, поэтому удаление имени означает удаление файла.
— unlink ("fred");
— chomp ($n=<stdin>);
unlink $n;
— unlink ("a. txt","b. txt");
— unlink <*.c>;
Операция <*.c> применена в списочном контексте для выдачи списка имен файлов, что совпадают с образцом.
Функция unlink возвращает количество успешно удаленных файлов. Значение 0 – если удалить не удалось.
Какие файлы удалились – определить невозможно. Поэтому удалять следует в цикле по одному элементу. (В Win Perl из развертывания удаляется только один файл).
Пример. Удаление всех файлов, имена которых заканчиваются на .с
с выдачей сообщения об ошибке для каждого файла, который удалить нельзя.
foreach $file (<*.c>)
{ unlink ($file)||warn("Не могу удалить файл $file.$!");
}
Если return 1, то warn – пропускается. Это означает, что следующий файл успешно удален. Если return 0 — то warn работает.
Если unlink без аргументов, то работает $_. В этом случае удаляются файлы, имена которых в переменной $_.
Пример. Условие предыдущего примера
foreach (<*.c>)
{ unlink || warn("$_.$!");
}
Переименование
— rename ("fred","barn"); # fred – old, barn – new
— rename ($old, $new);
Возврат:
true – переименовано
false – нет
Работа с каталогами
1. Перемещение по дереву
chdir ("имя"var);
Аргументом может быть название каталога в кавычках или переменная, содержащая название каталога, куда нужно перейти.
Пример:
print "Куда?";
chomp ($wh=<STDIN>);
chdir $wh|| warn("Не могу перейти на $wh.$!");
Если просто chdir, то текущий – это начальный каталог. Для каждого процесса – свой текущий каталог. При запуске наследуется родительский, а потом уже при изменениях – это не влияет на другие каталоги процессов. Начальный для UNIX и NT. Для Windows-95 — это каталог, в котором был.
2. Дескрипторы каталогов
А. Как и для файлов операция opendir совмещает назначение и открытие.