Язык программирования Perl - Михаил Шохирев
Шрифт:
Интервал:
Закладка:
Подробное описание шаблонов и работы функций pack() и unpack() можно найти в стандартной документации с помощью все той же утилиты чтения документации:
perldoc perlpacktut
Для чтения двоичных данных или текстовых данных фиксированной длины применяется функция read(), которой в качестве аргументов передаются файловый манипулятор, скалярная переменная для вводимых данных и размер считываемого блока данных. Вот так, например, выглядит типичный цикл чтения двоичных данных:
until(eof($fh)) { # читать до достижения конца файла # считать очередной блок данных и проверить его длину read($fh, $record, $record_size) == $record_size or die('Неправильная длина данных'); # распаковать данные по шаблону из $record в @data @data = unpack($template, $record); # обработать введенные данные... }
При работе с данными фиксированной длины обычной практикой является считывание или запись данных в произвольном месте файла, например, при изменении только что считанного блока данных. Для этого нужно позиционировать позицию чтения или записи. Это делается с помощью функции seek(), которой передается три аргумента: файловый манипулятор, смещение в байтах и указатель позиции отсчета. Позиция отсчета задается числами: 0 - от начала файла, 1 - от текущей позиции, 2 - от конца файла. Например:
seek($handle, 64, 0); # переместиться на 64 байта от начала seek($handle, 25, 1); # сместиться на 25 байт вперед seek($handle, -10, 2); # установиться на 10 байт до конца seek($handle, 0, 0); # установить позицию в начало файла
С помощью функции tell(), которая возвращает смещение относительно начала файла, можно узнать текущую позицию чтения-записи и использовать ее для дальнейших перемещений по файлу.
$pos = tell($handle); # запомнить текущую позицию в $pos seek($handle, $pos-5, 1); # сместиться на 5 байт назад
В следующем примере увеличивается поле счетчика длиной 2 байта, расположенное в файле с позиции $new_pos:
seek($file, $new_pos, 0); # установить позицию чтения $pos = tell($file); # и запомнить ее в переменной read($file, $number, 2); # прочитать 2-байтовое поле seek($file, $pos, 0); # установить в исходную позицию syswrite($file, ++$number, 2); # записать новое значение
Операции ввода-вывода с произвольным доступом часто используются для работы с базами данных, основанных на записях фиксированной длины, например, с файлами в формате DBF. Они позволяют организовать быструю выборку данных и запись измененных данных на прежнее место.
Перед выполнением операций ввода-вывода часто требуется узнать информацию об объектах файловой системы. В Perl есть набор унарных операций для удобной проверки различных характеристик файлов и каталогов. Они имеют вид флагов из одной латинской буквы с предшествующим знаком минус, после которого указывается имя проверяемого файла. Полный перечень операций проверки файлов приведен в таблице 9.3.
Таблица 9.3. Операции проверки файловОперацииОписание проверок-r -w -xФайл доступен для чтения / записи / исполнения (по effective UID+GID)-R -W -XФайл доступен для чтения / записи / исполнения (по real UID+GID)-o -OФайл принадлежит текущему пользователю по effective / real UID-e -zФайл существует (exists) / имеет нулевую длину (zero)-sФайл имеет ненулевой размер: возвращает размер в байтах (size)-f -dФайл является обычным файлом (file) / каталогом (directory)-l -S -pФайл является ссылкой / сокетом / именованным FIFO-каналом (pipe)-b -cФайл является блочным / символьным специальным файлом-u -g -kДля файла установлен бит setuid / setgid / sticky-tФайловый манипулятор связан с терминалом (tty)-T -BФайл является текстовым (text) / двоичным (binary)-M -A -CВремя изменения (modification) / доступа (access) / изменения (change) индексного узла (inode) файла в днях относительно времени начала выполнения программы ($^T)
Вот несколько типичных примеров использования операций проверки файлов для контроля доступности данных:
open($f1, "<$file1") # открыть файл на чтение, if (-e $file1) && # если он существует и (-r $file1); # он доступен на чтение open $f2, ">$file2" # открыть файл на запись, if -w $file2; # если в него можно писать $file_size = -s $file; # узнать размер файла print "$file - является каталогом!" if -d $file;
В Perl есть целый набор встроенных функций для работы с файлами, с помощью которых можно манипулировать с самими файлами, а не с данными, хранящимися в них.
Функция rename() переименовывает файл, возвращая логическое значение: 1 при успешном изменении имени и 0 - в противном случае. Ей передаются старое и новое имя файла с абсолютным или относительным путем.
$ok = rename("$path/$old_name", "$path/$new_name");
Функция unlink() удаляет файл или список файлов, возвращая число 1 при успешном удалении и 0 - при ошибке.
unlink($list, $of, $files); # удалить список файлов unlink $file if -e $file; # удалить файл, если он существует
Функция truncate() усекает файл до указанного размера и возвращает число 1 в случае успешного выполнения усечения и неопределенное значение undef - при возникновении ошибки. Файл может задаваться именем или файловым манипулятором. Например:
$ok = truncate($file, $size);
Функция stat() возвращает информацию о файле в виде списка или пустой список при неудаче. Файл может задаваться манипулятором файла или выражением со значением имени файла:
@info = stat($file); # получить всю информацию о файле $size = $info[7]; # размер файла в байтах $modified = localtime($info[9]); # время изменения файла
Подробное описание всех элементов информационного списка можно найти в документации, указав утилите чтения документов имя функции следующим образом:
perldoc -f stat
Функция utime() изменяет у файла (или нескольких файлов из заданного списка) время доступа и время модификации, задаваемые числовыми значениями.
utime($access_time, $modified_time, @list_of_files);
Кроме упомянутых, есть еще встроенные функции для изменения прав доступа и владельца файла, для чтения и создания символических и жестких ссылок. Немало разных функций для работы с файлами имеются в стандартной библиотеке модулей Perl, еще больше можно найти в хранилище модулей CPAN.
Помимо работы с файлами, в Perl есть необходимый набор встроенных функций для работы с каталогами. Нужно иметь в виду, что успешность выполнения операций с каталогами зависит от набора прав пользователя, от лица которого выполняется Perl-программа.
Функция mkdir() создает каталог с указанным именем. Вторым аргументом функции можно задавать права доступа для создаваемого каталога (в соответствии со стандартом POSIX). Возвращает число 1 при успешном создании или 0 при ошибке. Причину неудачи при создании каталога можно узнать из специальной переменной $!, которая содержит сообщение об ошибке.
$ok = mkdir $directory_name; # создать каталог mkdir $dir, $access_rights; # создать каталог, задав права
Функция rmdir() удаляет каталог по его имени, если он пуст, возвращает число 1 при успешном удалении каталога или 0 в случае ошибки. Тогда из переменной $! можно выяснить подробности неудачи:
$ok = rmdir $directory_name; # удалить каталог
Функция chdir() изменяет текущий каталог на значение строкового выражения, содержащего имя нового текущего каталога. Если имя каталога не задано, она переходит в домашний каталог пользователя, используя значение элемента $ENV{"HOME"} или $ENV{"LOGNAME"} из специального хэша %ENV, который содержит значения переменных окружения операционной системы. Возвращает число 1 при успешном переходе в другой каталог или 0 в случае возникновения ошибки.
$ok = chdir $new_dir; # перейти в каталог $new_dir chdir; # перейти в домашний каталог
Много других возможностей по работе с каталогами предоставляют функции из стандартной библиотеки модулей Perl. Например, функция cwd() из стандартного модуля Cwd возвращает имя текущего (рабочего) каталога во время выполнения программы:
use Cwd; # подключить библиотечный модуль Cwd my $current_work_directory = cwd; # запросить текущий каталог