| Содержание | Предисловие | В |
Глава 17В этой главе:
Открытие и закрытие DBM-хешей Использование DBM-хеша Базы данных произвольного доступа с записями фиксированной длины Базы данных с записями переменной длины (текстовые) Упражнения Работа с пользовательскими базами данныхDBM-базы данных и DBM-хетиВ большинстве UNIX-систем єсть стандартная библиотека, которая называется DBM. Зта библиотека представляет собой простую сБиблиотека DBM довольно проста, но, учитывая ее доступность, неко-торые системные программы активно используют зту библиотеку для своих довольно скромных нужд. Например,Per! обеспечивает доступ к такому же механизму DBM довольно умным способом: посредством процесса, похожего на открытие файла, с DBСоздание нового злемента в зтом массиве влечет за собой немедленное изменение в базе данных. Удаление злемента приводит к удалению значення из DBM-базы данных и т.д.* Размер, количество и вид ключей и значений в DBM-базе данных ограничены. В зависимости от того, какой версией библиотеки DBM вы пользуетесь, зти же ограничения могут иметь мОткрытие и закрытие DBM-хешей Чтобы связать DBM-базу данных с DBM-массивом, применяется функ-ция dbmopen, которая используется следующим образом:dbmopen( %ИМЯ МАССИВА, "имя_ОВМ-фа{та", $режим}Параметр %имя_массива — зто имя Perl-хеша. (Если в данном хеше уже єсть значення, они выбрасываются.) Хеш соединяется сПараметр $режим — зто число, которое соответствует битам прав доступа к названным двум файлам, если файлы создаются заново. Обычно оно указывается в восьмеричномdbmopen(%FRED, "mydatabase", 0644); # открьггь %FRED на mydatabaseЗтот вызов связывает хеш %fred с файлами mydatabase. dirФункция dbmopen возвращает значение "истина", если базу данных можно открыть или создать; в противном случае возвращается "ложdbmopen(%A,"/etc/xx",undef) || die "cannot open DBM /etc/xx"; * Если, как в данном случае, (^awibi/etc/xx.dirvi/etc/xx.pagoTKpbnb нельзя, то вызов dbmopenDBM-массив остается открытым в течение выполнения всей программы. Когда программа завершается, разрывается и связь с DBM-базой данных. Зту связь можно разорвать и способом, близким к закрытию дескриптора файла —dbmclose(%A); Как и функция close, dbmclose возвращает значение "ложь", если что-нибудь происходит не так, как надо.Использование DBM-хеша После открытия базы данных обращения к DBM-хешу преобразуются в обращения к базе данных. Изменение значення в хеше или ввод в него нового значення вызывает немедленную запись соответств $FRED{"fred"} = "bedrock"; # создать (или обновить) злемент delete $FRED("barney"}; # удалить злемент базн д} Последний цикл должен просмотреть весь файл на диске дважды: один раз для выборки ключей, а второй — для поиска значений, соответсwhile (($key, $value) = each(%FRED) ) ( print "$key has value of $value\n"; } Если вы обращаетесь к системним DBM-базам данных, например к базам данных, созданным системами sendmail и Например, чтобы найти имя merlyn в базе данных псевдонимов, можно сделать так:dbmopen(%ALI, "/etc/aliases", undef) I I die "no aliases?"; $value °= $ALI {"merlyn\0" 1; # обратите внимание на добавленный NULchop ($value) ; # удалить добавленный NULprint "Randal's mail is headed for: $value\n"; # показать результатВ вашей версии UNIX база данных псевдонимов может храниться не в каталоге /etc,Базы данных произвольного доступа с записями фиксированной длины Еще одна форма хранения данных — файл на диске, предназначенный для записей фиксированной длины. В зтой схеме данные состоНапример, у нас может быть ряд записей со следующими данными: 40 символов — имя, один символ — инициал,Perl поддерживает программы, которые используют файл с подобными записями. Помимо того, что вы уже знаєте, понадобятся еще несколько операций:1. Открытие файла на диске для чтения и записи.2. Переход в зтом файле на произвольную позицию.3. Выборка данных фиксированной длины, а не до следующего символа новой строки.4. Запись данных блоками фиксированной длины.В функции open перед спецификацией, задающей способ открытия файла (для чтения или записи), необходимо записать знак плюс, указав таким образом, что данный файл в действителopen (А, "+<Ь"); # открьеть файл b для чтения-записи (ошибка, если файл отсутствует)open(C, "+>d"); # создать файл d с доступом для чтения-записиopen (Е, "+”f"); # открить или создать файл f с доступом для чтеОтметим, что все, что мы сделали — зто добавили знак плюс к специфи-кации, задающей направление ввода-вывода данных в файл.Открыв файл, мн должны перейти на определенную позицию в нем. Зто делается с помощью функции seek, которая принимает те же три параметра, что и библиотечная програм ма./yeeAseek(NAMES,4*83,0) ; После перемещения указателя в файле на нужную позицию следующая операция ввода или вывода будет начинаться с зтой позиции. Для вывода используйте функцию print,print NAMES pack("A40 A A40 s", $first, $middle, $last, $age); В данном случае pack задает 40 символов для $ fНаконец, нам нужно узнать, как выбрать конкретную запись. Конструк-ция <names> возвращает все данные, начиная с текущей позиции і до следующего символа новой строки, о$count = read(NAMES, $buf, 83); Первый параметр функции read — дескриптор файла. Второй параметр —Получив зти 83-символьные данные, разбейте их на компоненты с помощью функции unpack:($first, $middle, $last, $age) = unpack("A40 A A40 s", $buf); Как видно, строки, определяющие формат, в функциях pack и unpack —$names = "А40 А А40 s";$names_length = length(pack($names)); # вероятно, 83Базы данных с записями переменной длины (текстовые) Многие системные базы данных ОС UNIX (й довольно большое число пользовательских баз данных) представляют собой набори поняКорректируются зти базы данных в основном с помощью простих текстовых редакторов. Процедура обновлення базы данных состоит из чтения ее в какую-то временную область (память или другой дисковий файл), внесення необходимых изменений и либ Perl поддерживает редактирование такого типа в строчно-ориентирован-ных базах данных методом редактирования на месте. Редактирование на месте —Чтобы запустить режим редактирования на месте, присвойте значение скалярной переменной $ л і. Оно иКогда используется конструкция о и переменная $ЛI имеет значение, отличное от u$ARGV = shift 6ARGV; open(ARGV,"<$ARGV") ; rename($ARGV,"$ARGV$AI"); ## INPLACE ## unlink($ARGV); ## INPLACE ## open(ARGVOUT,">$ARGV"); ## INPLACE ## select(ARGVOUT) ,- ## INPLACE ## В результате в операции "ромб" при чтении используется старый файл, а запись в дескриптор файла по умолчанию осуществляется в новую копию зтого файла. Старый файл остается в резервной копии, су Типичные значення переменной $ЛI — .bak или ~, т.е. резеВот как можно путем редактирования файла паролей заменить регистра-ционный shell всех пользователей на /bin/sh'.8ARGV = ("/etc/passwd"); # снабдить информацией операцию "ромб"$"1 == ".bak"; # для надежности записать /etc/passwd.bakwhile (о) { # основной цикл, по разу для каждой строки файла# /etc/passwd s#: ( л: ] *$#:/bin/sh#; # заменить shell# /etc/passwd Как видите, зта программа довольно проста. Однако ее можно заменить всего лишь одной командой с несколькими аргументами командной строки, например: perl -р -і.bak -е 's#: [л:]*$#:/Ключ -р охватывает вашу программу циклом while, который включает оператор print.Более подробно аргументы командной строки рассматриваются в книге Programming Perl и на man-страницеУпражнения 1. Создайте программу, которая открывает базу данных псевдонимов send-mail и выводит на зкран все ее злементы.2. Создайте две программы: одну для чтения данных с помощью опе-рации о, разбивки их на слова и обновлення DBM-файла с запомина-нием числа зкземпляров каждого слова, а втору |
| Содержание | Предисловие | В |