Perl запись в файл. Файловые операции Perl. Чтение и запись файлов

В Perl предусмотрен набор унарных операций, возвращающих значение только одного поля структуры индексного дескриптора. Эти операции в документации называются "операциями -X", так как их названия состоят из дефиса с последующим единственным символом. Все они являются унарными именованными операциями и имеют свой приоритет в сложных выражениях.

Полный перечень унарных операций проверки файлов

R Файл может читаться эффективным uid/gid -w Записывать в файл может эффективный uid/gid -x Файл может выполняться эффективным uid/gid -o Владельцем файла является эффективный uid/gid -R Файл может читаться действительным uid/gid -W Записывать в файл может действительный uid/gid -X Файл может выполняться действительным uid/gid -O Владельцем файла является действительный uid/gid -e Файл существует -z Размер файла равен нулю -s Размер файла отличен от нуля (возвращает размер) -f Файл является обычным (plain) файлом -d Файл является каталогом -l Файл является символической ссылкой -p Файл является именованным програмным каналом (FIFO) или проверяемый дескриптор связан с програмным каналом -S Файл является сокетом -b Файл является специальным блочным файлом -c Файл является специальным символьным файлом -t Дескриптор файла связан с терминалом -u У файла установлен бит setuid -g У файла установлен бит setgid -k У файла установлен бит запрета (sticky bit) -T Файл является текстовым файлом -B Файл является двоичным (противоположным текстовому) -M Возраст файла в днях на момент выполнения программы -A То же для врмени последнего обращения к файлу -C То же для время последней модификации индексного дескриптора файла

Унарные операции применяются к строке, содержащей имя файла, к выражению, вычисляемым значением которого является имя файла, или к файловому дескриптору Perl. Если параметр операции не задан, то она тестирует файл, чье имя содержится в специальной переменной $_. Каждая операция проверки атрибута файла возвращает 1, если файл обладает соответствующим атрибутом, пустую строку "" в противном случае и неопределенное значение undef, если указанный в параметре файл не существует.

Несколько слов об алгоритме определения текстовых и двоичных файлов (операции -T и -B). Эти операции анализируют содержимое первого блока файла на наличие "странных" символов - необычных управляющих последовательностей или байтов с установленными старшими битами. Если обнаружено достаточно большое количество подобных символов (больше 30%), то файл считается двоичным, иначе текстовым. Любой файл с пустым первым блоком рассматривается как двоичный.

Если эти операции применяются к файловым дескрипторам Perl, то проверяется содержимое буфера ввода/вывода, а не первого блока файла. Обе эти операции, примененные к файловым дескрипторам, возвращают булево значение Истина, если связанный с дескриптором файл пуст или установлен на конец файла.

При выполнении унарных именованных операций проверки файла на самом деле неявно вызывается функция stat(), причем результаты ее вычисления кэшируются, что позволяет использовать специальный файловый дескриптор _ для ускорения множественных проверок файла:

If(-s("filename") && -T _) { # Что-то делаем для текстовых файлов не нулевого размера. . . . . . . . . . . . . . }

chdir

Изменение текущего рабочего каталога на каталог, определяемый значением параметра ВЫРАЖЕНИЕ. Если параметр опущен, домашний каталог становится текущим. Возвращает бклево значение Истина в случае успешного выполнения операции замены текущего каталога и Ложь в противном случае.

Chdir [ВЫРАЖЕНИЕ]

chmod

chmod СПИСОК

Функция chmod() изменяет права доступа для файлов, представленных в списке, переданном ей в качестве параметра. Первым элементом этого списка должно быть трехзначное восьмеричное число, задающее права доступа для владельца, пользователей из группы, в которую входит владелец, и прочих пользователей. Каждая восьмеричная цифра определяет право на чтение файла, запись в файл и его выполнение (в случае если файл представляет выполняемую программу) для указанных выше групп пользователей. Установленные биты ее двоичного представления отражают соответствующие права доступа к файлу. Например, если установлены все три бита (восьмеричное число 7), то соответствующая группа пользователей обладает всеми перечисленными правами: может читать из файла, записывать в файл и выполнять его. Значение равное 6 определяет право на чтение и запись, 5 позволяет читать из файла, выполнять его, но не позволяет записывать в этот файл и т.д. Обычно не выполняемый файл создается с режимом доступа 0666 - все пользователи могут читать и записывать информацию в файл, выполняемый файл - с режимом 0777. Если владелец файла желает ограничить запись в файл пользователей не его группы, то следует выполнить следующий оператор:

Chmod 0664, "file.dat";

Возвращаемым значением функции chmod(), как и функции chown(), является количество файлов из списка, для которых операция изменения прав доступа завершилась успешно.

В операционных системах DOS и Windows имеет значение только установка режимов доступа владельца.

chown

chown СПИСОК

Любой пользователь, создавший собственный файл, считается его владельцем. Изменить владельца файла из сценария Perl можно функцией chown(). Параметром этой функции является список, первые два элемента которого должны представлять числовые идентификаторы uid и gid. Остальные элементы списка являются именами файлов, для которых изменяется владелец. Эта функция возвращает количество файлов, для которых операция изменения владельца и группы прошла успешно.

Пример:

@list = (234, 3, "file1.dat", "file2.dat"); $number = chown(@list); warn "Изменился владелец не у всех файлов!" if $number != @list-2;

Изменить владельца файла может только сам владелец или суперпользователь (обычно системный администратор) системы UNIX. В операционных системах с файловой системой отличной от UNIX (DOS, Windows) эта функция отрабатывает, но ее установки не влияют на доступ к файлу.

chroot

Определяет новый корневой каталог для всех относительных (начинающихся с косой черты "/") имен файлов процесса пользователя и порожденных им процессов. Не меняет текущий рабочий каталог. В отсутствии параметра используется значение специальной переменной $_. Может вызываться только суперпользователем.

Chroot ИМЯ_КАТАЛОГА

close

close ДЕСКРИПТОР

По завершению работы с файлом он закрывается функцией close(). Единственным необязательным параметром этой функции является дескриптор, ассоциированный с файлом.

Эта функция возвращает значение Истина, если успешно очищен буфер ввода/вывода и закрыт системный дескриптор файла. Вызванная без параметра, функция close закрывает файл, связанный с текущим дескриптором, установленным функцией select().

При возникновении ошибок закрытия файла их можно обнаружить применяя специальную переменную $!: close (FILE) or die "Ошибка закрытия файла: $!";

closedir

Закрывает каталог, ассоциированный с дескриптором каталога, заданным параметром ДЕСКРИПТОР. Возвращает булево значение Истина, если каталог успешно закрыт.

Closedir ДЕСКРИПТОР

fcntl

Реализует системную команду Unix fcntl(2). Перед использованием следует получить доступ к определениям системных констант оператором use Fcntl.

Возвращаемое значение: если системная функция возвращает -1, то функция Perl - неопределенное значение; если системная функция возвращает 0, то функция Perl строку "0 but true"; если системная функция возвращает какое-либо другое значение, функция Perl возвращает это же значение.

Fcntl ДЕСКРИПТОР, ФУНКЦИЯ, СКАЛЯР

glob

Возвращает найденные в текущем каталоге файлы, имена которых удовлетворяют заданному шаблону (с использованием метасимволов Unix "*","?"). Значением выражения должна быть строка, содержащая шаблон имен файлов.

Glob ВЫРАЖЕНИЕ

ioctl

Реализует системную команду Unix ioctl(2). Перед использованием следует получить доступ к определениям системных констант оператором require "ioctl.ph";

Возвращаемое значение:

  • если системная функция возвращает -1, то функция Perl - неопределенное значение;
  • если системная функция возвращает 0, то функция Perl строку "0 but true";
  • если системная функция возвращает какое-либо другое значение, функция Perl возвращает это же значение.
fcntl ДЕСКРИПТОР, ФУНКЦИЯ, СКАЛЯР

link

Link СТАРЫЙ, НОВЫЙ

lstat

Возвращает список значений полей структуры индекснего дескриптора символической ссылки на файл. Если параметр опущен, то используется значение специальной переменной $_.

Lstat [ДЕСКРИПТОР] lstat [ВЫРАЖЕНИЕ]

Используется для получения информации о символических ссылках. Возвращает список значений полей структуры индексного дескриптора самой ссылки, а не файла, на который она ссылается. Эта функция работает аналогично функции stat().

mkdir

Создание нового каталога с именем, заданным в параметре КАТАЛОГ, и режимом доступа, определяемым параметром РЕЖИМ. При успешном создании каталога возвращает булево значение Истина, в противном случае Ложь и в переменную $! заносится сообщение об ошибке.

Mkdir КАТАЛОГ, РЕЖИМ

open

open ДЕСКРИПТОР, ИМЯ_ФАЙЛА; open ДЕСКРИПТОР;

Для доступа к файлу из программы Perl необходим дескриптор. Для создания дескриптора используется функция open(). При выполнении операции open с заданым в параметрах именем файла открывается соответствующий файл и создается дескриптор этого файла. В качестве дескриптора файла можно использовать выражение - его значение и будет именем дескриптора. Имя файла задается непосредственно в виде строкового литерала или выражения, значением которого является строка. Операция open без имени файла открывает файл, имя которого содержится в скалярной переменной $ДЕСКРИПТОР, которая не может быть лексической переменной, определенной функцией my().

Пример:

#! perl -w $var = "out.dat"; $FILE4 = "file4.dat"; open FILE1, "in.dat"; # Имя файла задано строкой open FILE2, $var; # Имя файла задано переменной open FILE3, "/perlourbook/01/".$var; # Имя файла вычисляется в выражении open FILE4; # Имя файла в переменной $FILE4

Если задано не полное имя файла, то открывается файл с указанным именем и расположенный в том же каталоге, что и программа Perl. Можно задавать полное имя файла, однако следует иметь в виду, что оно зависит от используемой операйионной системы. Например, в Windows следует обязательно задавать имя диска: d:/perlbook/file1.doc

Любой файл можно открыть в одном из следующих режимов: чтения, записи или добавления в конец файла. Это осуществляется присоединением соответствующего префикса к имени файла:

  • < (чтение)
  • > (запись)
  • >> (добавление)

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

Запись информации в файл, открытый в режиме записи, осуществляется в начало файла, что приводит к уничтожению содержащейся в нем до его открытия информации.

Информация, содержащаяся в файле, открытом в режиме добавления, не уничтожается, новые записи добавляются в конец файла.

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

Perl позволяет открыть файл еще в одном режиме - режиме чтения/записи.

Для этого перед префиксом чтения <, записи > или добавления >> следует поставить знак +.

  • +< - сохраняют содержимое открываемого файла
  • +> - сначало очищает содержимое открываемого файла
  • +>> - сохраняют содержимое открываемого файла, запись в файл всегда осуществляется в конец содержимого файла

opendir

Открытие каталога, имя которого равно значению параметра ВЫРАЖЕНИЕ, и связывает его с дескриптором, определяемым параметром ДЕСКРИПТОР. Имена дескрипторов каталогов хранаятся в собственном пространстве имен таблицы имен Perl.

Opendir ДЕСКРИПТОР, ВЫРАЖЕНИЕ

readlink

Возвращает значение сиволической ссылки, определяемой параметром ВЫРАЖЕНИЕ, если символические ссылки реализуются операционной системой; в противном случае - фатальная ошибка. Если при получении значения символической ссылки были получены системные ошибки, возвращает неопределенное значение и в специальную переменную $! заносится сообщение об ошибке. Если параметр опущен, используется значение переменной $_.

Readlink [ВЫРАЖЕНИЕ]

rename

Переименовывает файл. Возвращает 1 в случае успешного переименования и 0 в противном случае.

Rename СТАРОЕ_ИМЯ, НОВОЕ_ИМЯ

stat

В файловой структуре UNIX информация о файле храниться в его индексном дескрипторе (inode). Структура индексного дескриптора состоит из 13 полей, для которых используются специальные обозначения:

Поле Описание
dev Номер устройства в файловой системе
ino Номер индексного дескриптора
mode Режим файла (тип и права доступа)
nlink Количество жестких ссылок на файл (в отсутствии ссылок равно 1)
uid Числовой идентификатор владельца файла
gid Числовой идентификатор группы владельца файла
rdev Идентификатор устройства (только для специальных файлов)
size Размер файла в байтах
atime Время последнего обращения к файлу с начала эпохи
mtime Время последнего изменения файла с начала эпохи
ctime Время изменения индексного дескриптора с начала эпохи
blksize Предпочтительный размер блока для операций ввода/вывода
blocks Фактическое количество выделенных блоков для размещения файла

Не все перечисленные поля структуры индексного дескриптора поддерживаются всеми файловыми системами.

Функция stat() предназначена для получения значений полей структуры индексного дескриптора файла. Ее единственным параметорм может быть либо имя файла, либо дескриптор открытого в программе файла. Она возвращает список из 13 элементов, содержащих значения полей структуры индексного дескриптора файла в том порядке, как они перечислены в таблице.

Типичное использование в программе Perl представлено ниже:

($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = stat($filename);

Присваивание значение полей списку скалярных переменных с идентификаторами, соответствующими названиям полей, способствует лучшей читаемости программы, чем присваивание массиву скаляров:

@inode = stat($filename);

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

Если при обращении к функции stat() не указан параметр, то она возвращает структуру индексного дескриптора файла, чье имя содержится в специальной переменной $_.

Функция получения информации о файле при успешном выполнении в списковом контексте возвращает список значений полей структуры индексного дескриптора файла или пустой список в случае неудачного завершения. В скалярном контексте она возвращает булево значение Истина или Ложь в зависимости от результатов своего выполнения.

Для удобства использования информации о файле функция stat() при успешном выполнении кэширует полученные значения полей. Если вызвать эту функцию со специальным дескриптором файла _ (символ подчеркивания), то она возвратит информацию, хранящуюся в кэше от предыдущего ее вызова. Это позволяет проверять различные атрибуты файла без повторного вызова функции stat() или сохранения результатов ее выполнения в переменных программы.

Функцию stat() можно использовать для получения структуры индексного дескриптора не только файла, но и жестких ссылок на него, а также каталогов, так как они являются также файлами, блоки данных которых содержат имена файлов каталога и их числовых индексных дескрипторов.

symlink

Symlink СТАРОЕ_ИМЯ, НОВОЕ_ИМЯ

umask

Устанавливает маску режима доступа процесса, заданную значением параметра ВЫРАЖЕНИЕ (восьмеричное число), и возвращает предыдущее значение маски режима доступа.

Umask ВЫРАЖЕНИЕ

unlink

Удаление файлов, определенных параметром СПИСОК. Возвращает количество успешно удаленных файлов.

Unlink СПИСОК

utime

utime СПИСОК

В структуре индексного дескриптора файла существует три поля, в которых храниться время последнего обращения (atime) к файлу, его изменения (mtime) файла и изменения индексного дескриптора (ctime). Функцией utime() можно изменить время последнего обращения и модификации файла. Ее параметром является список, содержащий имена обрабатываемых файлов, причем первые два элемента списка - числовые значения нового времени последнего доступа и модификации:

@files = ("file1.dat", "file2.dat"); $now = time; utime $now, $now, @files;

В этом фрагменте кода время последнего доступа и модификации файлов из списка @files изменяется на текущее время, полученное с помощью функции time.

Отметим, что при выполнении функции utime() изменяется и время последней модификации индексного дескриптора (ctime) - оно устанавливается равным текущему времени. Возвращаемым значением является количество файлов, для которых операция изменения времени последнего доступа и модификации прошла успешно.

О том, что такое файл писать я надеюсь ненужно, но думаю нужно подумать над тем, что с ними можно делать, как видно из заголовка статьи, на Perl. Ну, приступим...

В этой статье обсудим:

  • Манипуляции с файлом
  • Работа со строками в файле

    Что такое файловые манипуляторы, и с чем их едят

    Доступ к файлам осуществляется с помощью файловых манипуляторов, которые представляют собой так сказать синоним файла. Они не являются переменными, а поэтому их нельзя непосредственно присваивать другим переменным или передавать в функции (для этого нужно, что называется, пойти другим путем).

    Есть и стандартные Перловские файловые манипуляторы. Они называются STDIN (стандартный ввод), STDOUT (стандартный вывод) и STDERR (стандартный поток ошибок). Например параметры скрипту из формы передаются именно через STDIN (при условии использования метода POST).

    Если понадобится создать копию файлового манипулятора (не файла, а только манипулятора по которому осуществляется доступ к файлу), то можно воспользоваться функцией open (о ней подробнее поговорим позже).

    Пример: open(FILL,"file.txt"); open(FAIL,"<&FILL");

    О присваивании переменным файловых манипуляторов:

    $handle=*FILL; или передать его в функцию: some_sub(*FILL);

    И под конец скажу, что файловые манипуляторы в Perl используются не только для связи с, собственно, файлом. Они могут быть связаны с каким-нибудь процессом, сокетом и т.д. Но это не входит в тематику статьи.

    Манипуляции с файлом

    Открытие файла осуществляется функцией open.

    Open(FFF,"> file.txt");

    Разберемся. У функции три параметра: FFF - название файлового манипулятора (его задаете вы), режим доступа ">" и "file.txt" - имя нужного вам файла. Есть три основных режима: ">" - запись,"<"- чтение, ">>"- добавление в файл.

    Есть еще функция sysopen. Работа с ней не на много сложнее, чем с open, зато с ее помощью вы сможете более детально "сказать" системе о ваших намерениях (то есть то, что вы хотите сделать с файлом).

    В sysopen три обязательных параметра и один необязательный.

    Например: sysopen(FH,$name, $flags, $param);

    FH - собственно, файловый манипулятор, $name - имя файла в чистом виде (без ">" и др.). В $flags помещаем число, полученное объединением нижеописанных констант через OR (|):

    Это, конечно, не полный перечень, но здесь перечислены самые необходимые и часто используемые константы.

    И наконец $param. Этот параметр задает маску доступа к файлу и записывается в восьмеричной системе. Обычно используется значение 0666 (значение по умолчанию, то есть если $param опущен), или 0777. Первое значение используется для обычных файлов, второе же для каталогов и исполняемых файлов.

    Пример открытия файла для записи (если не найден - создается):

    Sysopen(FH,"data.txt",O_WRONLY|O_TRUNC|O_CREATE);

    Запись в файл делаем функцией print.

    Print(FFF "oppa! Пишем в файл!");

    Здесь FFF - имя файлового манипулятора, а строка в кавычках - текст, который мы хотим записать в файл, ассоциированный с FFF.

    Если до попытки открытия файла не существовало, то функция open его создаст, а если файл был, и он был не пустой, то после вышеуказанной функции print, в нем ничего не останется от предыдущей информации, а записана будет та ерунда, которую я там вписал.

    Как уже было сказано, существуют три стандартных файловых манипулятора, и при опущенном файловом манипуляторе функция print осуществит вывод в STDOUT (то же относится к функциям printf и write). Чтобы изменить направление вывода в Perl предусмотрена функция select (правда не только для этого). Пример:

    Open(F1,"> one.txt"); print "Файл открыт! Пишем в STDOUT."; $old_point=select(F1); print "Пишем в файл one.txt"; select($old_point); print "Снова пишем в STDOUT."; close(F1);

    Закрываем файл функцией close.

    Close(FFF);

    Принцип убирать за собой прививается всем с детства. Давайте не забывать об этом и в программировании, хотя при завершении процесса, в котором был открыт данный файл, файл закрывается автоматически.

    Блокировка файла

    Во-первых для чего? А для того, что если несколько процессов хотят одновременно заполучить доступ к файлу, причем на запись, причем еще и хотят туда что-то писать (кошмар), то представьте, что оказалось бы, если не этот чудный механизм блокировки. Он позволяет, грубо говоря, ставить процессы в очередь. Делаем так:

    Open(FIL,"> file.dat"); flock(FIL,2); close(FIL);

    О функциях open и close уже говорили, а на flock остановимся немного подробнее. Она получает два параметра - файловый манипулятор и, образно говоря, категорию блокировки.

  • 1 совместная блокировка (для чтения)
  • 2 монопольная блокировка (для записи)
  • 4 асинхронный запрос блокировки
  • 8 снятие блокировки

    Про снятие блокировки: блокировка автоматически снимается при завершении процесса, вызванного текущим скриптом, либо при закрытии файлового манипулятора, который "привязан" к заблокированному файлу. Если вы снимаете блокировку вручную, будьте аккуратны - вы даете возможность другому процессу делать с (ВНИМАНИЕ!) не закрытым вами файлом все что ему угодно! Последствия могут быть, мягко говоря, неприятные, а грубо говоря - непредсказуемые (для вас непредсказуемые).

    Работа со строками в файле

    Так как именно те файлы, которые содержат строковую информацию составляют наибольший интерес для, собственно, человека, то и речь сейчас пойдет именно о них.

    Для чтения строк из файла используется файловый манипулятор "поставленный" в <>.

    Например:

    Open(FIL,"data.txt"); while() { # делаем что-то с каждой строкой файла }

    Если не указано иначе, то внутри такого цикла используется стандартная переменная "$_", а номер строки записывается в "$.". Так как конец строки обозначается спецсимволом, например "\n", для получения самой строки (без эдакого "хвоста") нужно ее усечь функцией chomp.

    Open(FIL,"data.txt"); while() { chomp; # отрезается спецсимвол от переменной $_ print; # пишем $_ на STDOUT }

    @strings=; foreach $line (@strings) { print $list; }

    Для передвижения по файлу используются функции tell и seek.

    Open(FIL,"data.txt"); $position=tell(FIL); print "Текущая позиция в файле $position. \n"; seek(FIL,$position+10,1); print "А теперь переместились на 10 байт к концу файла от текущей позиции. \n"; $position=tell(FIL); print "Теперь текущая позиция в файле $position. \n";

    Результат:

    Текущая позиция в файле 0. А теперь переместились на 10 байт к концу файла. Теперь текущая позиция в файле 10.

    Функция tell принимает в качестве параметра файловый манипулятор, а seek берет три параметра. Первый - файловый манипулятор, второй - смещение в байтах, третий - направление смещение. Есть три направления смещения: 0 - от начала файла, 1 - от текущей позиции, 2 - с конца файла.

    Нельзя сказать, что это все, что нам предлагает Perl для работы с файлами. Будем надеяться, что у меня будет время на то, чтобы написать о том, как работать с каталогами, тонкости при работе с бинарными файлами, объектно-ориентированный подход к управлению файлами и их содержимым.

  • #!/usr/bin/perl
    use strict;

    while ( ) { # результат чтения сохраняется в переменной $_
    chomp ; # отсекаем символ \n в переменной $_
    last if ($_ eq "exit" ) ;
    printf "Вы ввели "%s". Для выхода из цикла введите exit\n " , $_ ;
    }

    Заметьте также, что функция print была заменена на printf , которая должна быть хорошо знакома программистам на Си. Я полагаю, что вы уже знакомы с форматированным выводом. Если это не так — ничего страшного, всю необходимую информацию можно получить, выполнив команды perldoc -f printf и perldoc -f sprintf .

    Файлы — чтение и запись

    Чтение и запись в случае с файлами производится точно так же, как чтение из STDIN и запись в STDOUT или STDERR. Единственное, о чем следует позаботится — это создать дескриптор, связанный с заданным файлом.

    #!/usr/bin/perl
    use strict;
    # создаем файловый дескриптор
    open FID, "input.txt"
    or die "Failed to open input.txt: $!\n " ;
    my $i = 0 ;
    print "line " .++ $i . ": $_" while ( ) ;
    close FID; # закрываем файловый дескриптор

    Собственно создание файлового дескриптора происходит на четвертой строчке. Функция open принимает два аргумента — дескриптор и имя файла. В случае ошибки, например, если файла с именем input.txt не существует, функция вернет false, а сообщение об ошибке будет записано в переменную $! .

    Но что делает оператор «или» после вызова open? Конструкция вида «функция1 or функция2» встречается в perl-скриптах довольно часто, так что давайте разберемся, как она работает.

    Будем считать, что функция1 и функция2 возвращают ложь в случае ошибки и истину иначе. Сначала выполняется функция1. Если она завершается успешно, будет возвращено истинное значение и интерпретатору Perl следует вычислить «истина или (что-то, что вернет функция2)». Но «истина или ложь» = «истина или истина» = «истина». Другими словами, в этом случае результат не зависит от того, что вернет функция2, а значит не следует тратить время на ее выполнение.

    Если же функция1 завершится с ошибкой и вернет «ложь», то результат «ложь или функция2» напрямую зависит от того, что вернет функция2, значит в этом случае интерпретатор будет обязан ее вызвать. Таким образом конструкция «функция1 or функция2» означает «вызвать функцию1 и если она вернет ложь (и только в этом случае!) вызвать функцию2».

    Значит, если вызов open завершится неудачно, будет вызвана функция die , которая делает что? Как несложно догадаться по ее названию — выводит сообщение об ошибке и завершает работу скрипта. Остальная часть примера настолько тривиальна, что я не вижу смысла ее описывать.

    Только что мы рассмотрели открытие файла на чтение. Чтобы открыть файл на запись, нужно перед его именем указать > или >>:

    #!/usr/bin/perl
    use strict;
    # пример 1
    open FID, ">output1.txt" ; # один знак "больше"
    or die "Failed to open output1.txt: $!\n " ;
    print FID "111\n " ; # обратите внимание - запятой нет
    close FID;

    # пример 2
    open FID, ">>output2.txt" ; # два знака "больше"
    or die "Failed to open output2.txt: $!\n " ;
    print FID "222\n " ;
    close FID;

    В первом случае, если файл output1.txt уже существует, он будет очищен, иначе — файл output1.txt будет создан. Во втором случае, если файл output2.txt уже существует, запись будет производится в его конец, иначе также будет создан новый файл. Чтобы почувствовать разницу, можете несколько раз запустить этот скрипт и посмотреть, что будет записано в каждом из файлов.

    Здесь мы рассмотрели лишь самые распространенные способы вызова функции open . Вывод команды perdoc -f open занимает 19 килобайт. Это не случайно, ведь функцию open можно вызывать с тремя аргументами, с ее помощью можно сохранять файловые дескрипторы в скалярных переменных и даже перенаправлять данные в уже открытых дескрипторах. Разумеется, в рамках одной заметки я не могу рассказать о всех возможностях этой функции (более того — скорее всего я их всех и не знаю), так что можете считать чтение соответствующей документации домашним заданием.

    В заключение к этому разделу хотелось бы рассказать об интересной особенности оператора <>. Дело в том, что он может использоваться без указания файлового дескриптора:

    #!/usr/bin/perl
    print while (<> ) ; # аналогично print $_ while($_ = <>);

    В этом случае, если скрипт был вызван без аргументов, оператор будет производить чтение из STDIN. В противном случае все аргументы будут рассматриваться, как имена файлов. Чтение будет производиться по очереди из каждого файла. Можно сказать, что этот скрипт представляет собой аналог утилиты cat.

    Работа с каталогами

    Самый простой способ получить имена всего, что есть в каталоге — это воспользоваться функциями opendir и readdir :

    #!/usr/bin/perl
    use strict;
    opendir DIR, "/home/afiskon" or die $! ;
    while (my $fname = readdir DIR) {
    print "$fname\n " ;
    }
    closedir DIR;

    Тут все настолько просто, что даже комментировать не хочется. Давайте лучше сразу перейдем к более интересному примеру:

    #!/usr/bin/perl
    use strict;

    my @flist = glob "~/*.txt" ;
    print "$_\n " for (@flist ) ;

    Функция glob возвращает список файлов, как это сделала бы оболочка csh. Тильда означает домашний каталог, звездочка — любую последовательность символов. Также можно использовать знак вопроса, фигурные и квадратные скобки.

    Существует и более короткая запись:

    my @flist = <~/*. txt>; # полностью эквивалентно glob "~/*.txt"

    А еще можно так:

    print "$_\n " while (<~/*. txt> ) ;

    Использовать функцию glob лучше в тех случаях, когда в выражение нужно подставить переменную.

    Другие операции над файлами и каталогами

    Эта заметка была бы не полной, если бы я не рассказал, как в Perl создать/удалить каталог или определить размер файла. Но не беспокойтесь, этот раздел очень простой. Фактически сейчас моя задача — привести список функций и операторов, чтобы в случае необходимости вы знали, в какой мануал заглянуть (вы ведь уже запомнили команду «perldoc -f имя_функции», верно?) :

    # удаление одного или нескольких файлов
    # функция возвращает число успешно удаленных файлов
    unlink $file1 , $file2 , $file3 ;

    # а еще можно так:
    unlink glob "~/*.core" ;

    # переименовать или переместить файл
    rename $old , $new ;

    # создать каталог, второй аргумент представляет
    # собой права доступа и является необязательным
    mkdir $dir_name , 0755;

    # удалить пустой каталог
    rmdir dir;

    # сменить права доступа к файлу или файлам
    chmod 0755, $file1 , $file2 , $file3 ;

    # сменить владельцев файлов
    chown $user , $group , glob "*.txt"

    Также в Perl имеется несколько довольно полезных операторов:
    die "EPIC FAIL\n " ;
    }
    }

    С непривычки эти операторы могут показаться странными, но на самом деле они мало чем отличаются от банальных «больше» и «меньше». Полный список операторов этого типа можно посмотреть, выполнив команду perldoc -f -X .

    Заключение

    Мои поздравления! Вы только что закончили читать последнюю часть «Основ Perl». Теперь вы знаете, что в этом языке нет ничего мистического — он не то, чтобы невероятно сложен, очень даже читаем, если знаешь матчасть, и хорошо документирован. К сожалению, за кадром остались еще множество вопросов, например взаимодействие процессов, объектно-ориентированное программирование, регулярные выражения и многие другие. Если вы намерены продолжить изучение Perl, то я настоятельно рекомендую приобрести книги «Изучаем Perl» и «Perl: изучаем глубже», авторы - Шварц Р. и Феникс Т., пока их еще легко найти.

    Я надеюсь, что «основы» помогут вам написать ваши первые скрипты и разобраться в чужом коде. Со временем у вас будут возникать вопросы «а как мне сделать то-то» и «а что происходит в этом скрипте в строе N». Не ленитесь заглядывать в документацию и просить помощи у более опытных программистов на форумах, в чатах и в тематических сообществах (например, жж-сообществе ru_perl). И рано или поздно вы станете настоящим гуру языка Perl. Удачи!

    Дополнение. См также заметки, посвященные регулярным выражениям , объектно-ориентированному программированию в Perl и заливке модулей на CPAN . Можете считать их дополнениями к этой серии уроков.

    Perl использует технику, называемую переменную дескриптор файла для работы тип файла.

    Чтение или запись данных из файла требует использования дескрипторов файлов.

    Ручка файла (дескриптор файла) является наименовании соединений ввода / вывода.

    Perl предоставляет три файла ручками: STDIN, STDOUT, STDERR, представляющие стандартный ввод, стандартный вывод и стандартный вывод ошибок.

    Perl файлы могут быть открыты в следующих способов:

    Open FILEHANDLE, EXPR open FILEHANDLE sysopen FILEHANDLE, FILENAME, MODE, PERMS sysopen FILEHANDLE, FILENAME, MODE

    Параметр Описание:

    • EXPR: имя файла и тип доступа к файлу, состоящий из выражения.
    • РЕЖИМ: тип файла доступа.
    • Завивке: доступ Bit (биты прав доступа).

    Открытая функция

    Мы используем следующую функцию кода, чтобы открыть режим только для чтения (<), чтобы открыть файл file.txt:

    Open(DATA, "

    <Только для чтения представление.

    Код файла DATA Ручка используется для чтения файла, следующий пример будет открыть файл и содержимое файла на выходе:

    #!/usr/bin/perl open(DATA, "){ print "$_"; }

    Следующий код для записи (>) способ открыть файл file.txt:

    Open(DATA, ">file.txt") or die "file.txt 文件无法打开, $!";

    > Для режима записи.

    Если вам нужно открыть файл в режиме чтения-записи, перед> или <символ знак +, чтобы добавить:

    Open(DATA, "+

    Такой подход не удаляет содержимое исходного файла, если вы хотите удалить следующий формат:

    Open DATA, "+>file.txt" or die "file.txt 文件无法打开, $!";

    Если вы хотите подать дополнительные данные, дополнительные данные перед тем, вам нужно всего лишь открыть файл в режиме добавления:

    Open(DATA,">>

    >> Представляет добавлять данные в существующий файл, если вам нужно прочитать содержимое файла, чтобы добавить, чтобы добавить знак +:

    Open(DATA,"+>>file.txt") || die "file.txt 文件无法打开, $!";

    В следующей таблице перечислены различные режимы доступа:

    режим описание
    <Или г
    > Или ж
    >> Или Открыть для записи указатель файла в конец файла. Если файл не существует, делается попытка создать.
    + <Или г +
    +> Или ш + Открыть для чтения и записи, указатель файла в заголовок файла и размер файла обрезается до нуля. Если файл не существует, делается попытка создать.
    >> + Или + Открыть для чтения и записи указатель файла в конец файла. Если файл не существует, делается попытка создать.

    функция SysOpen

    ФункцияSysOpen аналогична открыть функцию, но они не являются такими же формой аргумента.

    Следующий пример основан на чтение и запись (+ <имя файла) способ, чтобы открыть файл:

    Sysopen(DATA, "file.txt", O_RDWR);

    Если вам необходимо обновить файлы, удаленные до того, как файл записывается следующим образом:

    Sysopen(DATA, "file.txt", O_RDWR|O_TRUNC);

    Вы можете использовать O_CREAT, чтобы создать новый файл, O_WRONLY записи только режим, O_RDONLY режим только чтения.

    Параметры завивке восьмеричное значение свойства указывает на то, что права доступа к файлам после создания, по умолчанию0x666.

    В следующей таблице перечислены возможные значения режима:

    режим описание
    O_RDWR Открыть для чтения и записи, указатель файла в заголовке файла.
    O_RDONLY Открыть только для чтения указатель файла в заголовке файла.
    O_WRONLY Открыть для записи указатель файла в заголовке файла и размер файла обрезается до нуля. Если файл не существует, делается попытка создать.
    O_CREAT Создайте файл
    O_APPEND Append File
    O_TRUNC Размер файла режется до нуля
    O_EXCL Если вы используете O_CREAT файл существует, он возвращает сообщение об ошибке, он может проверить, существует ли файл
    O_NONBLOCK Неблокирующая операций ввода / вывода, так что мы либо успеха или немедленно возвращает ошибку, не блокирован.

    Закрыть функция

    После использования в файле, закройте файл, который вы хотите обновить входные и выходные буферы дескриптор файла, связанные с закрытием файла имеет следующий синтаксис:

    Close FILEHANDLE close

    FILEHANDLE для указанного дескриптора файла, если успешно закрыта возвращается верно.

    Close(DATA) || die "无法关闭文件";

    Чтение и запись файлов

    Чтение и запись информации в файл Есть несколько различных способов:

    оператор

    Основной метод чтения информации из открытого дескриптора файла является оператор. В скалярном контексте он возвращает одну строку из дескриптора файла. Например:

    #!/usr/bin/perl print "本教程网址?\n"; $name = ; print "网址:$name\n";

    После реализации описанной выше процедуры следующая информация, мы вводим вывод URL оператор печати:

    Когда мы используем оператор, который возвращает дескриптор файла для каждой строки в списке, например, мы можем импортировать все строки в массив.

    Реализация создает import.txt файл, следующим образом:

    $ cat import.txt 1 2 3

    #!/usr/bin/perl open(DATA,"; print @lines; # 输出数组内容 close(DATA);

    функция ЕОКП

    xgetc функция возвращает один символ из указанного FILEHANDLE, если вы не указываете обратный STDIN:

    Getc FILEHANDLE getc

    В случае возникновения ошибки, или дескриптор файла в конце файла, то она возвращает ФДООН.

    функция чтения

    Функция чтения используется для обработки информации, считанной из буфера файла.

    Эта функция используется для чтения двоичных данных из файла.

    Read FILEHANDLE, SCALAR, LENGTH, OFFSET read FILEHANDLE, SCALAR, LENGTH

    Параметр Описание:

    • FILEHANDLE: дескрипторов файлов, используемых для хранения уникального идентификатора для файла.
    • СКАЛЯР: Начать чтение позиции.
    • Длина: длина содержимого чтения.
    • OFFSET: смещение.

    В случае успешного возвращения, чтобы прочитать количество прочитанных байтов, возвращает 0, если конец файла, если произошла ошибка возврата UNDEF.

    функция печати

    Для вся информация считывается из функций дескриптор файла на заднем конце основной функции заключается в написании печати:

    Print FILEHANDLE LIST print LIST print

    Используйте файл и функции печати может обрабатывать результаты выполнения к выходным устройствам (STDOUT: стандартный вывод), например:

    Print "Hello World!\n";

    копирование файлов

    В следующем примере мы открываем существующий файл file1.txt, и читать его каждую строку записывается в файл file2.txt в:

    #!/usr/bin/perl # 只读方式打开文件 open(DATA1, "file2.txt"); # 拷贝数据 while() { print DATA2 $_; } close(DATA1); close(DATA2);

    Переименовать файл

    Ниже приведены примеры, мы уже существующий файл file1.txt переименовать file2.txt, каталог, указанный в / USR / w3big / тест / в:

    #!/usr/bin/perl rename ("/usr/w3big/test/file1.txt", "/usr/w3big/test/file2.txt");

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

    Удалить файлы

    Следующие примеры показывают, как мы используем функциюUNLINK , чтобы удалить этот файл:

    #!/usr/bin/perl unlink ("/usr/w3big/test/file1.txt");

    Укажите расположение файла

    Вы можете использовать функциюСКАЖИТЕ, чтобы получить местоположение файла, а также указать местоположение в файле с помощью функции искать:

    скажите функцию

    Функция скажите используется для получения местоположения файла:

    Tell FILEHANDLE tell

    Если FILEHANDLE функция возвращает позицию указателя файла в байтах. Если вы не укажете возврат к умолчанию выбирается ручкой файла.

    искать функцию

    искать () функция используется для перемещения через файл дескриптор файла читать и писать указатели путь для чтения или записи файла в байтах чтения и записи:

    Seek FILEHANDLE, POSITION, WHENCE

    Параметр Описание:

    • FILEHANDLE: дескрипторов файлов, используемых для хранения уникального идентификатора для файла.
    • ПОЛОЖЕНИЕ: указывает количество байтов дескриптора файла (чтение-запись указателя позиции), чтобы переместить.
    • ОТКУДА: представляет собой дескриптор файла (для чтения и записи указателей местоположения) начинают, когда начальное положение, вы можете принимать значение 0, 1; обозначают начало файла, текущей позиции и конец файла.

    Seek DATA, 256, 0;

    информация о файле

    Perl файловые операции также может проверить, существует ли файл и читать и писать.

    Что я могу создать file1.txt файл, например, в следующем:

    $ cat file1.txt www..txt"; my (@description, $size); if (-e $file) { push @description, "是一个二进制文件" if (-B _); push @description, "是一个socket(套接字)" if (-S _); push @description, "是一个文本文件" if (-T _); push @description, "是一个特殊块文件" if (-b _); push @description, "是一个特殊字符文件" if (-c _); push @description, "是一个目录" if (-d _); push @description, "文件存在" if (-x _); push @description, (($size = -s _)) ? "$size 字节" : "空"; print "$file 信息:", join(", ",@description),"\n"; }

    Вышеприведенная программа, выход:

    File1.txt 信息:是一个文本文件, 15 字节

    Файл операторы тестирования в следующей таблице:

    операторы описание
    Файл первого обращения времени (единицы: дней)
    -B Является ли это двоичный файл
    Файл (индексных дескрипторов) инод время модификации (единицы измерения: дней)
    Файл последнего изменения времени (единицы измерения: дней)
    Все файлы являются реальными UID
    -R Файл или каталог может быть прочитан реальным UID / GID
    -S Сокет (Socket)
    -T Является ли это текстовый файл
    -W Файл или каталог может быть записан в режиме реального UID / GID
    -X Файлы или каталоги могут быть выполнены в режиме реального UID / GID
    -b Файл блок-специальное (специальный блок) (например, монтирования диска)
    Символ-специальное (специальные символы) файл (например, устройства ввода / вывода)
    -d каталог
    Имя файла или каталога существует
    -f Обычный файл
    -g Файл или каталог имеет атрибут setgid
    -k Файл или каталог имеет липкий бит
    -l Это является символической ссылкой
    Все файлы доступны UID
    -p Файл является именованным каналом (FIFO)
    -r Файлы могут быть эффективно UID / GID чтения
    -s Файл или каталог существует и не 0 (возвращает число байт)
    -t Ручка Файл TTY (функция isatty система () возвращает результат, имя файла не может использовать этот тест)
    -u Файл или каталог имеет атрибут Setuid
    -w Файлы могут быть записаны в действительный UID / GID
    -x Файлы могут быть выполнены эффективно UID / GID
    -z Файл существует, размер 0 (константа каталога ложно), то есть, пуст ли файл,

    Perl имеет доступ к тем же основным, помогающим управлять исполнением программ дескрипторам файлов, а именно как: STDIN, STDOUT и STDERR. Более того, возможности для работы с дескрипторами файлов, которые указывают на реальные файлы, в Perl очень обширны и позволяют делать так, чтобы программы обрабатывали файлы любым необходимым образом. С помощью дескрипторов файлов можно открыть файл, передать его в массив, записать информацию в новый файл или даже выполнить все эти операции сразу со многими файлами одновременно.

    Самым простым дескриптором файлов является ромбическая операция о, у которой в принципе вообще нет никакого постоянного дескриптора: она представляет собой просто способ, позволяющий рассматривать входящий файл (или набор файлов) из командной строки как входной дескриптор файла до тех пор, пока в этом файле остаются строки для считывания. Чтобы воспользоваться ромбической операцией, подготовьте цикл наподобие такого, как показан ниже:

    Затем запустите свою программу, указав одно или более имен файлов в командной строке:

    # ./myscript.pl filel.txt file2.txt

    Это приведет к распечатке содержимого всех указанных файлов, почти так же, как и при использовании команды cat. Такой способ получения доступа к содержимому файлов является удобным и быстрым. Однако он также и достаточно ограниченный; ромбическая операция в принципе представляет собой "вырожденный вариант" истинного дескриптора файла. Давайте рассмотрим несколько заданных должным образом дескрипторов, чтобы увидеть, что они на самом деле могут делать.

    Название дескриптора файла принято вводить заглавными буквами. Создать его можно командой open(). После этого с ним можно выполнять следующие действия: читать из него информацию, передать в него информацию или закрыть его. Ниже показано, как можно открыть файл и распечатать его строка за строкой:

    1. open (FH,"/path/to/filel.txt");

      while ($thisline = )

    2. chomp ($thisline);

      print "$i: $thisline\n";

    Бывает так, что Perl не удается открыть файл, либо потому что он не существует, либо потому что установленные полномочия не разрешают выполнять чтение этого файла, либо еще по какой-то причине. Вы можете перехватить подобные события, воспользовавшись операцией die: если при вычислении выражения управление перейдет к die, он передаст свой аргумент (если таковой имеется) на стандартный вывод и выполнение сценария завершится. Ниже показан наиболее распространенный способ применения операции die при открытии файлов:

    open (FH,"/path/to/filel. txt") || die ("Невозможно открыть filel.txt!");

    Выполнение записи в файлы является немного более сложной задачей, поточу что существует так много различных способов того, как ее можно выполнить, Главное, запомните, что для записи можно применять любой дескриптор, который разрешается использовать в командной строке, такой как > (перезапись) или >>(добавление), или даже | (конвейер). Последний может пригодиться, скажем, для того, чтобы сценарий записывал свой вывод в электронное сообщение (обратите внимание на упрощенный метод прохода через массив @contents и распечатки каждой строки):

      open (FH,">/path/to/file2.txt");

      print FH $_ foreach (@contents);

    1. open (MAIL,"| /usr/sbin/sendmail -oi -t");

      print MAIL "Subject: Важная информация!\n\n";

      print MAIL $_ foreach (@contents);

    Дескриптор файла передается в качестве аргумента команде print; здесь важно понимать следующее: если только не был указан какой-то другой дескриптор, предполагается, что этим аргументом является встроенный дескриптор файлов (стандартный вывод). Также еще имеется дескриптор (стандартный ввод). Чтобы указать дескриптор устройства ввода-вывода, который должен использоваться по умолчанию, применяйте функцию select(

    В таком случае вам не придется все время вводить print FH. Однако вам обязательно нужно будет изменить дескриптор обратно ка STDOUT. когда вы закончите работать с FH.

    Для работы с каталогами доступны свои функции: opendir () и readdir (); вы можете открыть каталог и прочитать его содержимое в массив следующим образом:

      opendir (DIR,"/path/to/dir");