Recently in Указатели файлов, файлы или директории Category

Функция open открывает файл, имя которой задается в EXPR, и связывает его с внутренним указателем FILEHANDLE.

Простой пример открытия файла для чтения:

open(my $fh, '<', "input.txt") or die $!;

и для записи:

open(my $fh, '>', "output.txt") or die $!;

Если FILEHANDLE является неопределенной скалярной переменной (а также массивом или элементом хэша), переменной присваивается ссылка на новый анонимный указатель файла. Иначе, если FILEHANDLE является выражением, его значение используется в качестве имени существующего файлового дескриптора. (Так как возвращаемое значение интерпретируется как символическая ссылка, необходимо, чтобы это выражение было вне области действия use strict 'refs'.)

Если не указан параметр EXPR, то ведется поиск скалярной переменной с тем же именем, что и FILEHANDLE. Эта переменная должна содержать имя файла и необязательный режим. (Заметим, что лексические переменные, объявленные оператором my, не будут работать для этих целей; поэтому, если вы используете my, укажите EXPR в вашем вызове open.)

Если указано три или более аргументов, тогда подразумевается, что режим открытия и имя файла указаны раздельно. Если MODE содержит '<' или пуст, то файл открывается для чтения. Если MODE содержит '>', файл очищается и открывается для записи, при необходимости создается. Если MODE содержит '>>', файл открывается для дозаписи, также создается при необходимости.

Можно поместить символ '+' перед любым из символов '>' или '<' чтобы открыть файл одновременно для чтения и записи. Так как режим '+>' затирает содержимое файла прежде чем можно будет что-нибудь из него прочесть, то режим '+<' почти всегда предпочтительнее для чтения/обновления по записи. Можно рассматривать файл, открытый в режиме обновления, как базу данных с произвольным доступом и перемещаться к байту с заданным номером при помощи seek, но переменная длина записей в обычных текстовых файлах делает непрактичным использование режима чтения-записи для обновления таких файлов. Лучший подход к обновлению говорится в описании параметра командной строки i в спецификации perlrun. Файл создается с режимом доступа 0666, данный режим зависит от текущей umask процесса.

Все эти префиксы соответствуют режимам 'r', 'r+', 'w', 'w+', 'a', и 'a+' в функции fopen(3).

Если open вызывается с одним или двумя аргументами, то режим и имя файла должны быть объединены(в таком порядке), возможно разделенные пробелом. Если режим не указан, тогда предполагается режим для чтения '<'.

  open(my $fh, "<:encoding(UTF-8)", "filename")
  || die "Ошибка при открытии файла в кодировке UTF-8: $!";

открывает UTF-8 закодированный файл, см. perluniintro. Отметим, что если дисциплины указаны в трех-аргументной форме open, то по умолчанию дисциплины, содержащиеся в ${^OPEN}, игнорируются. (см. perlvar, обычно устанавливается прагмой open или c помощью ключей командной строки -CioD)

Функция open() возвращает ненулевое значение в случае успеха и неопределенное значение в противном случае.

Если Perl исполняется на системе, которая различает текстовые и двоичные(бинарные) файлы, то при открытии двоичного файла следует указать двоичный режим с помощью функции binmode. Основное отличие систем, в которых требуется binmode - в формате текстовых файлов. Системам подобным Unix, Mac OS, и Plan 9, функция binmode не требуется, потому что в файлах данных систем каждая строка завершается одним символом, соответствующим тому, что на языке Си определяется как перевод строки - "\n".

Сегодня рассматриваются особые операторы в Perl - "Операторы проверки файлов". Особые тем, что действуют как обычные унарные операторы, но при этом внутренне взаимодействуют с операционной системой. Они принимают один аргумент, являющийся именем файла или его дескриптором, и проверяют, обладает ли этот файл некоторым свойством. Так как данный тип операторов тесно связан с системными вызовами stat и файлами, он рассматривается в разделе Функции: Указатели файлов, файлы или директории

Статья является частью документации  Встроенные функции Perl

  • -X FILEHANDLE
  • -X EXPR
  • -X DIRHANDLE
  • -X

    Проверка файла, где X - один из перечисленных далее символов. Унарный оператор принимает один аргумент, это может быть имя файла, файловый дескриптор, либо дескриптор каталога, и проверяет соответствующий файл на соответствие условию. Ели аргумент не указан, проверяет $_, кроме работы с ключом -t, который использует STDIN. Если не оговорено иное, возвращает 1 для успешной проверки и '' для не успешной, либо неопределенное значение если файл не существует. Несмотря на забавные имена, приоритет у файловых проверок такой же как и у прочих именованных унарных операторов. Оператор может быть один из:

    -w # Файл доступен для записи текущему пользователю или группе (effective uid/gid)
    -x # Файл доступен для выполнения текущему пользователю или группе (effective uid/gid)
    -o # Файл принадлежит текущему пользователю (effective uid)
    
    -R # Файл доступен для чтения реальному пользователю или группе (real uid/gid)
    -W # Файл доступен для записи реальному пользователю или группе (real uid/gid)
    -X # Файл доступен для выполнения реальному пользователю или группе (real uid/gid)
    -O # Файл принадлежит реальному пользователю (real uid)
    
    -e # Файл существует
    -z # Файл имеет нулевой длины (пуст)
    -s # Файл имеет ненулевую длину ( возвращает размер в байтах )
    
    -f # Обычный файл.
    -d # Файл является каталогом.
    -l # Файл является символической ссылкой.
    -p # Файл либо файловый дескриптор являются именованным каналом (FIFO).
    -S # Файл является сокетом.
    -b # Блочный файл.
    -c # Символьный файл.
    -t # Дескриптор файла открыт в текущем терминале (tty).
    
    -u # Для файла установлен бит setuid
    -g # Для файла установлен бит setgid
    -k # Для файла установлен "липкий бит" (sticky bit)
    
    -T # Файл является текстовым в формате ASCII (эвристическая догадка).
    -B # Файл является "Двоичным"(бинарным) (в противоположность -T).
    
    -M # Время, прошедшее от последней модификации файла до запуска сценария, в днях.
    -A # Время, прошедшее от последнего обращения к файлу до запуска сценария, в днях.
    -C # Время, прошедшее от последнего изменения индексного дескриптора (inode) до запуска сценария
    

    Например:

    while (<>) {
    	chomp;
    	next unless -f $_;	# пропустить "особые" файлы
    	#...
    }
    

    Интерпретация операторов прав доступа (-r, -R, -w, -W, -x и -X) основывается исключительно на свойствах файла и пользовательском и групповом идентификаторах пользователя (uids, gids). Могут быть другие причины, по которым не удается читать, записывать или выполнять файл, например, управление доступом сетевых файловых систем, ACL (списки управления доступом), файловые системы только для чтения, и нераспознанные форматы исполняемого файла. Заметим, что использование вышеупомянутых шести операторов для тестирования файла, может привести к ошибке в случае, если в это время над файлом производятся какие либо операциии, что может вызвать зависание, состояние гонки и прочие неприятности.

    Также отметим, что для суперпользователя на локальной файловой системе, проверки -r, -R, -w, -W всегда возвращают 1, а -x и -X возвращают 1, если установлен хоть один бит исполнения. Поэтому в сценариях, выполняемых суперпользователем, может потребоваться выполнение stat(), чтобы определить действительный режим файла, либо временно установить другой идентификатор пользователя(анг. effective uid).

    Если используется ACL, полезна прагма filetest, которая обеспечивает более точные результаты чем stat(). При вызове use filetest 'access' вышеупомянутые операторы работают с использованием access(2) или аналогичных системных вызовов. Отметим также, что под действием этой прагмы операторы -x и -X могут возвращать истинное значение, даже если биты прав на выполнение не установлены ( или не выставлены какие либо дополнительные права ACL). Эта странность происходит в основе реализации низкоуровневых системных вызовов. Отметим также, что в связи с реализацией use filetest 'access', там, где распространяется её действие, специальный файловый дескриптор _ не будет кэшировать результаты выполнения операторов проверки файлов. За более подробной информацией обратитесь к документации прагмы filetest.

    Обратите внимание, что -s/a/b/ не производит подстановки с отрицанием. Однако -exp($foo) работает, как должно: только одиночные буквы после минуса трактуются как проверка файла.

    Ключи -T и -B работают следующим образом. Участок файла примерно в объеме первого блока исследуется на наличие необычных символов, таких как коды управления или байты с установленным старшим битом (не похожие на UTF-8). Если необычных символов слишком много (больше 30%), то файл считается двоичным(<-B>), иначе это текстовый(-T) файл. Также, любой файл считается двоичным, если он содержит в первом блоке нулевой байт ( символ ASCII NUL(\0) ). Если -T или -B применяется к дескриптору файла, то исследуется не первый блок файла, а текущий буфер ввода ( стандартный I/O или "stdio"). Оба оператора -T и -B возвращают истину для пустого файла, или файла, указатель которого находится в EOF|wiki - конце файла, если проверяется дескриптор. Поскольку нужно прочесть файл, чтобы выполнить проверку -T, в большинстве случаев лучше сначала сделать проверку с ключом -f, например next unless -f $file && -T $file.

    Если какому-либо из проверок файлов (или операторам stat или lstat операторам) передается специальный дескриптор файла, состоящий из "_" - одного символа подчеркивания, то используется структура stat предыдущей проверки файла (или оператора stat), что позволяет избежать нового системного вызова. (Это не работает для оператора -t, и нужно помнить, что lstat и -l сохраняют значения в структуре stat, относящиеся к символической ссылке, а не к реальному файлу. ) (Аналогично, если stat буфер был заполнен вызовом lstat, -T и -B сбросят его с результатом stat _). Например:

    stat($filename);
    print "Доступен для чтения \n" if -r _;
    print "Доступен для записи \n" if -w _;
    print "Исполняемый \n" if -x _;
    print "Установлен бит setuid\n" if -u _;
    print "Установлен бит setgid\n" if -g _;
    print "Установлен 'липкий бит'\n" if -k _;
    print "Текстовый\n" if -T _;
    print "Бинарный\n" if -B _;
    

    Начиная с версии Perl 5.9.1, как форма синтаксического сахара может использоваться стек операторов тестирования файла. Таким образом, -f -w -x $file эквивалентно -x $file && -w _ && -f _. ( Но если использовать возвращаемое значение -f $file в качестве аргумента для другого оператора, никакой особой магии не произойдет.


При переводе данной документации использовались следующие источники:

  •  http://translated.by/you/perlfunc/
  • Уолл Л., Кристиансен Т., Орвант Д. "Программирование на Perl" Символ-Плюс, 2006
  • Холзнер С. "Perl - специальный справочник" Питер, 2001

Statistic

About this Archive

This page is an archive of recent entries in the Указатели файлов, файлы или директории category.

Регулярные выражения и поиск по шаблону is the previous category.

Управление процессами is the next category.

Find recent content on the main index or look in the archives to find all content.