Шаг 38.
Доступ к файлу. Функции sysread(), syswrite() и sysseek()

    На этом шаге мы рассмотрим функции, реализующие не буферизованные операции.

    Операции <>, print, read, seek и tell относятся к операциям буферизованного ввода/вывода, т.е. они для повышения скорости выполнения используют буферы. Perl для выполнения операций чтения из файла и записи в файл предлагает также аналоги перечисленных функций, не использующие буферы при выполнении соответствующих операций с содержимым файла.

    Функции sysread и syswrite являются не буферизованной заменой операции <> и функции print, а функция sysseek заменяет функции seek и tell.

    Функции не буферизованного чтения и записи получают одинаковые параметры, которые соответствуют параметрам функции read:

    sysread ДЕСКРИПТОР, ПЕРЕМЕННАЯ, ДЛИНА [, СМЕЩЕНИЕ ]; 
    syswrite ДЕСКРИПТОР, ПЕРЕМЕННАЯ, ДЛИНА [, СМЕЩЕНИЕ ];

    Смысл всех параметров аналогичен параметрам функции read(). Возвращаемым значением этих функций является истинное количество прочитанных/записанных байт, 0 в случае достижения конца файла или undef при возникновении ошибки.

    Параметры функции sysseek о полностью соответствуют параметрам функции seek():

    sysseek ДЕСКРИПТОР, СМЕЩЕНИЕ, ТОЧКА_ОТСЧЕТА;

    Все, сказанное относительно использования функции seek(), полностью переносится и на ее не буферизованный аналог.

    Функциональность буферизованной операции tell() реализуется следующим вызовом функции sysseek:

    $position = sysseek F1, 0, 1;  #  Текущая позиция указателя файла.

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

#! perl -w 
use Fcntl;
# Открытие файла в режиме чтение/запись.
sysopen F1, "in.dat", O_RDWR;
# Чтение блока в 14 байт.
$read = sysread F1, $string, 14;
warn "Прочитано $read байт вместо 14\n" if $read != 14;
# Установка текущей позиции (на 15 байт).
$position = sysseek F1, 0, 1;
die "Ошибка позиционирования: $!\n" unless defined $position;
# Запись строки c текущей позиции.
$string = "Новое значение";
$written = syswrite F1, $string, length($string);
die "Ошибка записи: $!\n" if $written != length($string); 
# Закрытие файла.
close F1 or die $!;
Текст этого примера можно взять здесь.

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


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

    Со следующего шага мы начнем рассматривать операции с файлами.




Предыдущий шаг Содержание Следующий шаг