Доступ к файлам
Отрицательное значение смещения -n (n – целое число) означает, что из содержимого переменной ПЕРЕМЕННАЯ отбрасываются последние n байтов и к оставшейся строке добавляется запись, прочитанная из файла. Пример 7.5 демонстрирует чтение записей фиксированной длины в предположении, что файл in.dat содержит три строки данных:
One Two Three #! peri – w open(Fl, "in.dat") or die "Ошибка открытия файла: $!"; $string = "1234567890"; read Fl, $string, 6; I Чтение шести байт в переменную без смещения print $string,"\n"; # $string = "OneXnTw" read Fl, $string, 6, length($string); print $string,"\n"; # $string = "One\nTwo\nThre"
Функция length () возвращает количество символов (байтов) в строковых данных, хранящихся в скалярной переменной, переданной ей в качестве параметра. После выполнения первой операции чтения содержимое переменной $string было уничтожено, так как эта функция read о вызывалась без смещения. Тогда как при втором чтении хранившиеся данные в переменной $string были полностью сохранены.
Операции (), print, read, seek и tell относятся к операциям буферизованного ввода/вывода, т. е. они для повышения скорости выполнения используют буферы. Perl для выполнения операций чтения из файла и записи в файл предлагает также аналоги перечисленных функций, не использующие буферы при выполнении соответствующих операций с содержимым файла.
Функции sysread и syswrite являются не буферизованной заменой операции () и функции print, а функция sysseek заменяет функции seek и tell.
Функции не буферизованного чтения и записи получают одинаковые параметры, которые соответствуют параметрам функции read:
sysread ДЕСКРИПТОР, ПЕРЕМЕННАЯ, ДЛИНА [,СМЕЩЕНИЕ]; syswrite ДЕСКРИПТОР, ПЕРЕМЕННАЯ, ДЛИНА [.СМЕЩЕНИЕ];
Смысл всех параметров аналогичен параметрам функции read (). Возвращаемым значением этих функций является истинное количество прочитанных/записанных байт, о в случае достижения конца файла или undef при возникновении ошибки.
Параметры функции sysseek о полностью соответствуют параметрам функции seek():
sysseek ДЕСКРИПТОР, СМЕЩЕНИЕ, ТОЧКА_ОТСЧЕТА;
Все, сказанное относительно использования функции seek о, полностью переносится и на ее не буферизованный аналог.
Функциональность буферизованной операции tell () реализуется следующим вызовом функции sysseek:
$position = sysseek Fl, 0, 1; # Текущая позиция указателя файла
Пример 7.6 демонстрирует использование не буферизованных функций, ввода/вывода для обработки содержимого файла.
#! peri – w use Fcntl; # Открытие файла в режиме чтение/запись sysopen Fl, "in.dat", OJRDWR; # Чтение блока в 14 байт $read = sysread Fl, $string, 14; warn "Прочитано $read байт вместо 14\n" if $read!= 14; # Установка текущей позиции (на 15 байт). $position = sysseek Fl, 0, 1; die "Ошибка позиционирования: $!\п" unless defined $position; # Запись строки в текущей позиции $string = "Новое значение"; $written = syswrite Fl, $string, length($string); die "Ошибка записи: $!\n" if $written!= length($string); # Закрытие файла close Fl or die $!;
При работе с не буферизованными функциями ввода/вывода следует всегда проверять завершение операции чтения, записи или позиционирования. Стандартная система ввода/вывода, через которую реализуется буферизованный ввод/вывод, сама проверяет и отвечает за завершение указанных операций, если процесс был прерван на середине записи. При не буферизованном вводе/выводе об этом должен позаботиться программист.
Совет
При работе с одним и тем же файлом не следует смешивать вызовы буферизованных и не буферизованных функций ввода/вывода. Подобная практика может приводить к непредсказуемым коллизиям.