Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Операции с файлами. Получение информации о файле.



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

Есть и стандартные Перловские файловые манипуляторы. Они называются 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 ( | ):

O_RDONLY Только для чтения
O_WRONLY Только для записи
O_RDWR Для чтения и для записи
O_CREAT Если файла нет, создать!
O_APPEND Открытие в режиме присоединения
O_TRUNC Очищаем содержимое при открытии

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

И наконец $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(< FIL> )

{

# делаем что-то с каждой строкой файла

}

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

open(FIL, " data.txt" );

while(< FIL> )

{

chomp; # отрезается спецсимвол от переменной $_

print; # пишем $_ на STDOUT

}

Можно прочитать строки в массив:

@strings=< FIL>;

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, по существу, ничем не отличается от работы с любым другим файлом. Перед началом работы с ним его следует открыть обращением к стандартной функции opendir( ), которая создает в программе дескриптор каталога, используемый в качестве ссылки на открытый каталог при выполнении необходимых операций:

opendir ДЕСКРИПТОР, ИМЯ_КАТАЛОГА;

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

open CD, " /usr/out.dat"; # дескриптор файла

opendir CD, " /usr"; # Дескриптор каталога

ПРИМЕЧАНИЕ Использование одинаковых имен для дескрипторов файла и каталога может запутать самого пользователя. Однако для perl такой проблемы не существует: интерпретатор всегда точно знает, какой дескриптор следует использовать.

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

readdir ДЕСКРИПТОР;

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

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

Открытый в программе каталог закрывается функцией closedir( ) с единственным параметром — дескриптором каталога:

closedir ДЕСКРИПТОР;

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

Данная программа печатает содержимое каталога C: \DOS в операционной системе Windows.

Печать содержимого каталога

#! perl -w

opendir FDIR, " C: \\dos";

while( $name = readdir FDIR) {

print(" $name\n" );

}

closedir FDIR;

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

" c: \\dos\\" . $name

Можно также перед операциями с файлами какого-либо каталога сделать этот каталог текущим вызовом функции chdir( ), единственным необязательным параметром которой является полное или относительное имя каталога. В случае вызова без параметров функция устанавливает текущий каталог равным значению переменной окружения НОМЕ, если она установлена, или LOGDIR в противном случае. Получить или установить значение переменной окружения можно с помощью специального хэш-массива %ENV с ключом, равным имени переменной окружения, например $ENV{HOME} или $ENV{LOGDIR}. Если ни одна из указанных переменных окружения не установлена, то функция chdir без параметров ничего не делает. Она возвращает значение «истина», если произошло успешное обращение к соответствующей системной команде и текущий каталог изменен, и «ложь» в противном случае. В листинге 6.12 эта функция используется в алгоритме печати имен всех подкаталогов открытого каталога.

Листинг 6.12. Печать имен всех подкаталогов открытого каталога

#! perl -w

opendir FDIR, " c: \\dos";

chdir " c: \\dos"; # Устанавливаем текущий каталог

while( $name = readdir FDIR) {

print(" $name\n" ) if -d $name; # Является файл каталогом?

}

closedir FDIR;

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

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

mkdir ИМЯ_КАТАЛОГА [, РЕЖИМ];

Если задается не полное имя каталога, то он создается в текущем каталоге. В случае вызова функции с одним параметром режим доступа по умолчанию устанавливается равным 0777. Возвращаемым значением функции создания нового каталога mkdir( ) является «истина», если каталог создан, и «ложь», если произошла какая-либо ошибка, В последнем случае в специальной переменной $! хранится объяснение причины, по которой каталог не был создан.

Удалить каталог можно функцией rmdir( ) с параметром, содержащим строку с именем каталога. Если параметр не задан, то используется содержимое специальной переменной $_. Как и функция создания каталога, эта функция возвращает значение «истина» в случае успешного удаления каталога и «ложь» в противном случае, записывая в переменную $! объяснение возникшей ошибки.


 

8. Объявление и использование форматов.
 
Формат - языковая единица, которая требует обязательного объявления в программе Perl. Он используется в качестве " руководства" функцией write (), которая выводит на экран монитора, принтер или в файл информацию из программы в соответствии с записанными в формате " инструкциями" форматирования строк вывода. При объявлении формата определяется, как должна быть отформатирована каждая его строка при отображении на устройстве вывода. Формат объявляется в программе с помощью ключевого слова format, после которого следуют " инструкции" по форматированию определенных в нем строк. Завершается объявление формата строкой, первым символом которой является точка ".". Общий синтаксис конструкции объявления формата следующий: format ИМЯ_ФОРМАТА = ФОРМУЛЫ_СТРОК Пример использования формата приведен на 3 шаге. Параметр ИМЯ_ФОРМАТА представляет собой правильный идентификатор Perl. Он должен в точности соответствовать имени дескриптора файла, который используется в качестве единственного параметра в функции вывода write (). Например, если форматированный отчет выводится в файл, определенный в программе дескриптором FILE, то и имя формата должно быть также FILE. Функцию write() можно вызывать без параметра. В этом случае вывод осуществляется на стандартное устройство вывода (STDOUT), и имя формата в этом случае должно быть равным STDOUT. Если функцией select() установлен дескриптор файла вывода по умолчанию, то вывод функцией write() без параметра будет осуществляться в этот файл, причем имя формата вывода должно быть изменено на имя дескриптора файла. Замечания. 1. Объявление формата может осуществляться в любом месте программы. Обычно все объявления форматов задают либо в начале, либо в конце программы. 2. Имя формата обычно определяют прописными (большими) буквами, что способствует лучшей читаемости программы. В теле формата (до завершающей строки с точкой) определяются форматы для каждой строки вывода. Формат строки состоит из двух строк: первая, называемая строкой шаблонов, определяет, как отображается информация, вторая, называемая строкой переменных, задает переменные, содержащие выводимую информацию. Вместе эти две строки определяют формат и содержимое одной строки вывода функцией write (). Строка шаблонов печатается точно так, как она выглядит в тексте программы (включая пробельные символы), за исключением некоторых полей, в которые подставляются значения переменных из строки переменных. Эти поля(иногда их называют шаблоны, что и дало название соответствующей строке формата) начинаются с символа " @" или " ^", за которым следуют символы форматирования (таблица 1), определяющие ширину поля вывода значения переменной в символах и выравнивание выводимого значения внутри поля. Количество символов форматирования определяет ширину поля вывода, причем для одного поля все символы должны быть одинакового типа. Переменные, определяющие значения для полей строки шаблонов, задаются через запятую в строке переменных. Порядок их задания соответствует порядку задания полей вывода в строке шаблонов: значение первой переменной выводится в первое поле, второй - во второе и т. д. Все переменные в строке переменных вычисляются в списковом контексте. Это позволяет задавать выводимые значения в элементах массива скаляров. Замечание. Если строка шаблонов не содержит полей, то для нее не надо задавать строку переменных. Она отображается в точности так, как она задана в формате (смотри пример на 3 шаге).
Таблица 1.. Символы форматирования
Символ Описание
> Определяет символьное поле, в котором выводимое значение выровнено по правому краю
< Определяет символьное поле, в котором выводимое значение выровнено по левому краю
| Определяет символьное поле, в котором выводимое значение выровнено центру
# Определяет числовое поле (выводимое значение должно быть числом)
. Определяет положение десятичной точки в числовом поле (###.##)

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

В.Долженков Ю.Колесников: Excel 2000: BHV: 1999: 90

Нам необходимо распечатать отчет о всех продаваемых книгах. Воспользуемся форматами Perl. Программа примера 1 реализует поставленную задачу.

#! perl -wopen BOOKS, " < books"; # Открытие файла на чтение.while (< BOOKS> ) { # Разбиение строки по символу ': '. ($author, $title, $pub, $year, $price) = split (': '); write; # Форматный вывод строки.}format STDOUT =@< < < < < < < < < < < < < < < < < < < < < < < < < | @> > > > > > > > > > > | @| | @#### | @###.##р.$author, $title, $pub, $year, $price.

Текст этого примера можно взять здесь.

Результат отображения отчета на экране выглядит следующим образом:


Рис.1. Результат работы приложения

Обратите внимание, что все символы строки шаблонов печатаются именно в тех позициях, в которых они заданы, а в поля этой же строки, определенные символом " @ ", подставлены значения соответствующих переменных. Эти значения отображаются в соответствии с заданными символами форматирования: для переменной $author вывод выровнен по левому краю ( < ), для $title по правому краю ( > ), для $pub по центру ( | ) соответствующего поля. Значения переменных $уеаr и $price форматируются в соответствии с числовым форматом. Если бы эти переменные не содержали числовые значения, то интерпретатор Perl вывел бы предупреждающее сообщение.

Замечание. Символ начала поля в строке шаблонов (" @ " или " ^ " ) учитывается при подсчете ширины поля вывода.

Еще один нюанс, связанный с форматированием значений переменных. Если она содержит строковые данные, количество символов которых превосходит заданную ширину поля вывода, то лишние символы отсекаются справа. Именно это и произошло при выводе второй записи файла books: название второй книги напечатано не полностью.

Как поступать в таких случаях? Можно увеличить ширину поля, если позволяют параметры выводного устройства, а можно воспользоваться еще одним символом форматирования, который как раз и предназначен для решения подобных проблем. Прежде всего следует для задания начала поля использовать символ " ^ ". Его отличие от символа " @ " заключается в том, что до начала вывода строковых данных в поле Perl в промежуточном буфере аккумулирует слова из выводимых данных, формируя строку, длина которой не превышает ширину поля. После этого сформированные данные выводятся в строке, а значение переменной вывода модифицируется: она будет содержать оставшиеся слова. При последующем использовании этой переменной в другой строке переменных того же формата будут выводиться сохраненные в ней отсеченные данные. Это позволяет выводить длинные данные в нескольких строках в одном вертикальном блоке, если задавать для вывода оставшихся данных точно такое же поле, что и при выводе первой порции.

Заменим формат STDOUT программы примера 1 на следующий:

format STDOUT =@< < < < < < < < < < < < < < < < < < < < < < < < < | ^> > > > > > > > > > > | @| | @#### | @###.##р.$author, $title, $pub, $year, $price | ^> > > > > > > > > > > | | |~ $title.

Текст этого примера можно взять здесь.

Теперь вывод нашей программы будет выглядеть так:


Рис.2. Результат работы приложения

Символ тильда " ~ " в конце строки шаблона подавляет вывод пустых строк. Если не поставить его, то между первой и второй книгой в нашем отчете появится дополнительная строка, как если бы была выведена вторая строка шаблона с пустым значением переменной $title. Символ подавления вывода пустых строк можно задавать в любом месте строки шаблона, помня, что при выводе он отображается, как пробел.

В нашем примере мы знали, что данные в переменной $title не займут более двух строк при выводе. Поэтому в формате мы использовали эту информацию, добавив еще одну строку шаблона с переменной $title. А что делать, если не известно количество строк продолжения в которых будут выводиться данные? Можно воспользоваться двумя идущими подряд символами тильда вместо одного. В этом случае алгоритм буферизации данных по словам будет продолжаться до завершения вывода всех данных переменной. Если наш формат изменить на следующий:

format STDOUT =@< < < < < < < < < < < < < < < < < < < < < < < < < | ^> > > > > > > > > > > | @| | @#### | @###.##р.$author, $title, $pub, $year, $price | ^> > > > > > > > > > > | | |~~ $title.

Текст этого примера можно взять здесь.

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


Рис.3. Результат работы приложения

Таким способом можно организовать вывод длинных данных в вертикальные текстовые блоки с переносом по словам.

Прежде всего познакомимся с еще одним символом форматирования - символом " * ", который позволяет выводить длинные строковые данные в нескольких строках, длина которых равна максимальной ширине вывода устройства отображения (экрана монитора или принтера). Например, если переменная $record содержит строковые данные длиной более 80 символов и вывод осуществляется на экран монитора, то следующая программа:

#! perl -w

 

$record = " В.Долженков Ю.Колесников: Excel 2000: BHV: 1999: 90: Книга является....";

write;

 

format STDOUT =

@*

$record

.

отобразит на экране ее содержимое следующим образом:


Рис.1. Результат работы приложения

Текст этого примера можно взять здесь.

Достаточно часто случаются ситуации, когда отчет не помещается на одной странице. Можно печатать отчет в несколько страниц. Дело в том, что создание отчетов в Perl предполагает их вывод на принтер, а поэтому после вывода определенного количества строк функцией write() Perl автоматически выведет символ перехода на новую страницу и печать продолжится на следующей странице. По умолчанию количество строк на странице установлено равным 60. Эта величина хранится в специальной переменной $=, значение которой может быть изменено.

Итак, мы теперь знаем, что переход на новую страницу происходит автоматически, но нам хотелось бы, чтобы на каждой странице печатался верхний колонтитул, в котором отображалось бы наименование отчета и печатались номера страниц. И это возможно в Perl. Следует только задать формат со специальным именем, добавив к имени формата, по которому мы выводим информацию (в нашей программе STDOUT ), суффикс _TOP. Этот формат будет выводиться каждый раз, как начинается печать новой страницы.

Изменим программу из предыдущего шага, добавив в нее следующее объявление формата:

format STDOUT_TOP =

Книги на складе @> > > > > >

" стр. ".$%

Автор Название Издатель Год Цена

========================================================================

.

и явно зададим количество строк на странице, добавив перед циклом while оператор:

$= = 6;

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

#! perl -w

open BOOKS, " < books"; # Открытие файла на чтение.

$= = 6;

while (< BOOKS> )

{

# Разбиение строки по символу ': '.

($author, $title, $pub, $year, $price) = split (': ');

write; # Форматный вывод строки.

}

format STDOUT =

@< < < < < < < < < < < < < < < < < < < < < < < < < | ^> > > > > > > > > > > | @| | @#### | @###.##р.

$author, $title, $pub, $year, $price

| ^> > > > > > > > > > > | | |~~

$title

.

format STDOUT_TOP =

Книги на складе @> > > > > >

" стр. ".$%

Автор Название Издатель Год Цена

========================================================================

.

Текст этого примера можно взять здесь.

Результат работы приложения изображен на рисунке 2:


Рис.2. Результат работы приложения

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

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

 

 

 


 


Поделиться:



Популярное:

  1. Активны операции центрального банка.
  2. АНАЛИЗ СИЛЬНЫХ И СЛАБЫХ СТОРОН, ВОЗМОЖНОСТЕЙ И УГРОЗ организации (предприятия) системы потребительской кооперации
  3. Арифметические операции (АО)
  4. Больной оперируется по поводу острой кишечной непроходи-мости через 12 часов с момента заболевания. На операции об-
  5. В электроустановках напряжением до 1000В операции по установке и снятию заземлений разрешается выполнять одному работнику, имеющему группу III, из числа оперативного персонала.
  6. Векторы, операции над векторами. Скалярное, векторное, смешанное произведения векторов
  7. Влияние структуры операции на производительность
  8. Внешнеторговые операции и их виды
  9. Внешнеэкономические операции
  10. Вопрос 2. Структура и организация платежной системы. Базовая схема операции с банковской кредитной карточкой.
  11. Гид по Таро. Практическое решение проблем и получение советов
  12. Глава III. Получение впечатлений.


Последнее изменение этой страницы: 2016-05-03; Просмотров: 644; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.073 с.)
Главная | Случайная страница | Обратная связь