Открытие файла
Известно имя файла. Требуется открыть его для чтения или записи в Perl.
🕛 20.04.2010, 23:03
Функция open отличается удобством, sysopen - точностью, а модуль IO::File позволяет работать с анонимным файловым манипулятором. Функция open получает два аргумента: открываемый файловый манипулятор и строку с именем файла и специальными символами, определяющими режим открытия:open(SOURCE, "< $path") or die "Couldn't open $path for reading: $!\n"; open(SINK, "> $path") or die "Couldn't open $path for writing: $!\n";
где SOURCE - файловый манипулятор для ввода, a SINK - для вывода. Функции sysopen передаются три или четыре аргумента: файловый манипулятор, имя файла, режим и необязательный параметр, определяющий права доступа. Режим представляет собой число, конструируемое из констант модуля Fcntl:
use Fcntl; sysopen(SOURCE, $path, O_RDONLY) or die "Couldn't open $path for reading: $!\n"; sysopen(SINK, $path, O_WRONIY) or die "Couldn't open $path for writing: $!\n";
Аргументы метода new модуля IO::File могут задаваться в стиле как open, так и sysopen. Метод возвращает анонимный файловый манипулятор. Кроме того, также возможно задание режима открытия в стиле fopen(3):
use IO::File; # По аналогии с open $sink = IO::File->new("> $filename") or die "Couldn't open $filename for writing: $!\n";
# По аналогии с sysopen $fh = IO::File->new($filename, O_WRONLY|O_CREAT) or die "Couldn't open $filename for reading: $!\n";
# По аналогии с fopen(3) библиотеки stdio $fh = IO::File->new($filename, "r+") or die "Couldn't open $filename for read and write: $!\n";
Комментарий Все операции ввода/вывода осуществляются через файловые манипулятор независимо от того, упоминаются манипуляторы в программе или нет. Файловые манипуляторы не всегда связаны с конкретными файлами - они так применяются для взаимодействия с другими программами и в сетевых коммуникациях. Функция open также применяется для работы с файловыми дескрипторами. Функция open позволяет быстро и удобно связать файловый манипулятор с файлом. Вместе с именем файла передаются сокращенные обозначения стандарт иных режимов (чтение, запись, чтение/запись, присоединение). Функция не позволяет задать права доступа для создаваемых файлов и вообще решить, нужно ли создавать файл. Если вам потребуются подобные возможности, воспользуйтесь функцией sysopen, которая использует константы модуля Fcntl для управления отдельными компонентами режима (чтение, запись, создание и усечение). Большинство программистов начинает работать с open задолго до первого использования sysopen. В таблице показано соответствие между режимами функции open («Файл»), константами sysopen («Флаги») и строками fopen(3), передаваемыми IO::File->new («Символы»). Столбцы «Чтение» и «Запись» показывают, возможно ли чтение или запись для данного файлового манипулятора. «Присоединение» означает, что выходные данные всегда направляются в конец файла независимо от текущей позиции (в большинстве систем). В режиме усечения функция open уничтожает все существующие данные в открываемом файле. Файл Запись Чтение Присоединение Создание Очистка содержимого Флаги О_ Символы < файл Да Нет Нет Нет Нет RDONLY "r" > файл, режим открытия> Нет Да Нет Да Да WRONLY TRUNC GREAT "w" >> файл>, режим открытия> Нет Да Да Да Нет WRONLY APPEND GREAT "a" +< файл Да Да Нет Нет Нет RDWR "r+" +> файл, режим открытия> Да Да Нет Да Да RDWR TRUNC GREAT "w+" +>> файл>, режим открытия> Да Да Да Да Нет RDWR APPEND GREAT "a+" Подсказка: режимы +> и +>> почти никогда не используются. В первом случае файл уничтожается еще до того, как он будет прочитан, а во втором часто возникают затруднения, связанные с тем, что указатель чтения может находиться в произвольной позиции, но при записи на многих системах почти всегда происходит переход в конец файла. Функция sysopen получает три или четыре аргумента:
sysopen(FILEHANDLE, $name, $flags) or die "Can't open $name : $!"; sysopen(FILEHANDLE,$name, $flags, $perms) or die "Can't open $name: $!";
Здесь $name - имя файла без «довесков» в виде < или +; $flags - число, полученное объединением констант режимов O_CREAT, O_WRONLY, O_TRUNC и т. д. операцией OR. Конкретный состав доступных констант O_ зависит от операционной системы. Обычно встречаются следующие константы:
O_RDONLY Только чтение. O_WRONLY Только запись. O_RDWR Чтение и запись. O_CREAT Создание файла, если он не существует. O_EXCL Неудачное завершение, если файл уже существует. O_APPEND Присоединение к файлу. O_TRUNC Очистка содержимого файла. O_NONBLOCK Асинхронный доступ.
К числу менее распространенных констант принадлежат O_SHLOCK, O_EXLOCK, O_BINARY, O_NOCTTY и O_SYNC. Если функции sysopen не передается аргумент $perms, Perl использует восьмеричное число 0666. Права доступа задаются в восьмеричной системе и учитывают текущее значение маски доступа (задаваемой функцией umask) процесса. В маске доступа сброшенные биты соответствуют запрещенным правам. Например, если маска равна 027 (группа не может записывать; прочие не могут читать, записывать или выполнять), то вызов sysopen с параметром 066 создает файл с правами 0640 (0666&~027 = 0640). Если у вас возникнут затруднения с масками доступа, воспользуйтесь простым советом: передавайте значение 0666 для обычных файлов и 0777 для каталогов и исполняемых файлов. У пользователя появляется выбор: если ему понадобятся защищенные файлы, то может выбрать маску 022, 027 или антиобщественную маску 077. Как правило, решения из области распределения прав должны приниматься не программой, а пользователем. Исключения возникают при записи в файлы, доступ к которым ограничен: почтовые файлы, cookies в Web-броузерах, файлы .rhosts и т. д. Короче говоря, функция sysopen почти никогда не вызывается с аргументом 0644, так как у пользователя пропадает возможность выбрать более либеральную маску. Приведем примеры практического использования open и sysopen. Открытие файла для чтения:
open(FH, "< $path") or die $!; sysopen(FH, $path, O_RDONLY) or die $!;
Открытие файла для записи (если файл не существует, он создается, а если существует - усекается):
open(FH, "> $path") or die $!; sysopen(FH, $path, O_WRONLY|O_TRUNC|O_CREAT) or die $!; sysopen(FH, $path, O_WRONLY|O_TRUNC|O_CREAT, 0600) or die $!;
Открытие файла для записи с созданием нового файла (файл не должен существовать):
sysopen(FH, $path, O_WRONLY|O_EXCL|O_CREAT) or die $!; sysopen(FH, $path, O_WRONLY|O_EXCL|O_CREAT, 0600) or die $!;
Открытие файла для присоединения (в случае необходимости файл создается):
open(FH, ">> $path") or die $!; sysopen(FH, $path, O_WRONLY|O_APPEND|O_CREAT) or die $!; sysopen(FH, $path, O_WRONLY|O_APPEND|O_CREAT, 0600) or die $!;
Открытие файла для присоединения (файл должен существовать):
sysopen(FH, $path, O_WRONLY|O_APPEND) or die $!;
Открытиефайла для обновления (файл должен существовать):
open(FH, "+< $path") or die $!; sysopen(FH, $path, O_RDWR) or die $!;
Открытие файла для обновления (в случае необходимости файл создается):
sysopen(FH, $path, O_RDWR|O,CREAT) or die $!; sysopen(FH, $path, O_RDWR|O_CREAT, 0600) or die $!;
Открытие файла для обновления (файл не должен существовать):
sysopen(FH, $path, O_RDWR|O_EXCL|O_CREAT) or die $!; sysopen(FH, $path, O_RDWR|O_EXCL|O_CREAT, 0600) or die $!;
Маска 0600 всего лишь поясняет, как создаются файлы с ограниченным доступом. Обычно этот аргумент пропускается.