Поиск

Файлы DBM

При программировании на Perl использование DBM-файлов является самым простым способом хранения структурированных данных. Файлы DBM обладают одним замечательным свойством — в программах на Perl их можно напрямую связать с хэшем. При этом чтение и запись DBM-файлов сводится к простым операциям с хэшем, о которых шла речь на 7-м занятии, "Хэши".

Чтобы связать хэш с DBM-файлом, в Perl используется функция dbmopen, синтаксис которой выглядит так:

В результате выполнения этой функции указанный вами хэш подключается к DBM-файлу. Параметр имя_файпа на самом деле определяет два файла на жестком диске: имя_файла.pag и имя_файла. dir. Они используются Perl для хранения данных в иерархическом виде и быстрого доступа к ним. Эти файлы не являются текстовыми, поэтому их нельзя редактировать с помощью обычного текстового редактора. Кроме того, не обращайте внимания, если один из файлов имеет нулевую длину или его размер слишком велик по сравнению с сохраненными в нем данными. Это вполне нормальное явление.

Третий параметр функции dbmopen определяет права доступа, которые назначаются двум DBM-файлам при их создании. При работе в системе UNIX всегда используйте осмысленные значения прав_доступа. Это позволит контролировать доступ к вашим DBM-файлам. Например, значение кода прав доступа, равное 0666, обеспечивает доступ по чтению и записи к вашим DBM-файлам для всех пользователей данного компьютера; значение 0644 позволяет вам читать и записывать данные, в то время как для остальных пользователей обеспечивается только режим чтения. При работе в системе Windows данный параметр не играет особой роли, поскольку в ней не предусмотрены средства управления доступом. Поэтому всегда используйте значение 0666.

Функция dbmopen возвращает истинное значение, если операция подключения хэша к DBM-файлу прошла успешно. А теперь давайте рассмотрим пример:

После выполнения этого оператора устанавливается связь хэша %hash с DBM-файлом dbmfile. Для хранения хэша на диске Perl создает два файла: dbrafile.pag и dbmfile.dir. Если в последующих операторах значение элементов хэша будет изменено (как показано ниже на примере), Perl автоматически обновит соответствующие DBM-файлы:

Обращение к элементам хэша автоматически приводит к считыванию информации из DBM-файла, например:

Чтобы разорвать связь хэша %hash с DBM-файлом, используется функция dbmclose:

После выполнения этой функции элементы хэша ' кошачьи' и ' собачьи' останутся в DBM-файле. В результате при следующем запуске программы и связывании хэша %hash с DBM-файлами значение указанных элементов хэша будет восстановлено.

С хэшами, связанными с DBM-файлами, можно выполнять те же операции, что и с обычными хэшами, например использовать функции keys, values и delete. Чтобы очистить хэш (и соответственно DBM-файл), присвойте ему пустой список, как показано ниже:

Чтобы инициализировать хэш и соответствующий ему DBM-файл, после выполнения функции dbmopen присвойте ей нужные значения в списке.

Некоторые важные замечания

В этом разделе мы приведем несколько полезных замечаний, которые нужно иметь в виду при связывании хэша с DBM-файлом.

  • Ограничение на длину ключей и данных. Хотя в Perl не накладывается никаких специальных ограничений на длину ключей и данных хэша, тем не менее, при связывании с DBM-файлом суммарный размер одного ключа и хранимых в нем данных не должен превышать 1024 символа. Это ограничение обусловлено структурой DBM-файла. На общее число ключей в хэше не накладывается никаких ограничений, оно зависит только от типа используемой файловой системы.
  • После выполнения функции dbmopen первоначальные значения элементов хэша теряются. Поэтому лучше всего для операции связывания выбирать чистый хэш. Рассмотрим следующий пример:

    В этом примере после выполнения функции dbmopen ключ 'одногорбые' хэша %h теряется.

  • После выполнения функции dbmclose значения ключей связанного хэша теряются. Вот пример:

    В этом примере новый ключ 'парнокопытные' будет добавлен к DBM-файлу. Однако после выполнения функции dbmclose все ключи связанного хэша теряются, а хэш %h полностью очищается.

Обработка больших DBM-файлов

Предположим, что некоторый хэш связан с DBM-файлом. Для определенности будем считать, что вы пишете на Perl программу, которая сохраняет в файле сведения о сотрудниках: фамилия, должность, номер телефона и др. Очевидно, что если сотрудников достаточно много, то через некоторое время ваш хэш станет очень большого размера. Причина заключается в том, что каждый раз при запуске программы ее значения восстанавливаются из DBM-файла, добавляются в хэш и снова записываются в файл при завершении программы. Таким образом, если вы не предпримете специальных действий, значения из вашего хэша никогда не будут автоматически удаляться.

Если DBM-файл, называемый records, имеет большое количество информации, то при выполнении приведенного ниже фрагмента программы могут возникнуть проблемы.

He ищите ошибку в коде, ее там нет! Вначале выполняется связывание хэша %recs с DBM-файлом, затем с помощью оператора keys %recs из него извлекается список всех ключей, после чего в цикле foreach my $key распечатывается ключ и соответствующее ему значение.

Если список ключей хэша %recs велик, оператор keys %recs может выполняться достаточно продолжительное время и завершиться аварийно из-за нехватки оперативной памяти. Поэтому в Perl предусмотрена еше одна функция, предназначенная для обработки элементов хэша по одному за раз. Она называется each. Ее синтаксис выглядит так:

Функция each возвращает список, состоящий из двух элементов, — ключа и его значения, извлеченных из хэша. При каждом вызове этой функции она возвращает из хэша очередную пару ключ—значение. Если ключи в хэше исчерпаны, функция возвращает пустой список. Таким образом, приведенный выше фрагмент кода можно переписать так, чтобы с его помощью можно было обрабатывать хэши большого размера:

Функцию each можно использовать для перебора элементов любого хэша, а не только того, который связан с DBM-файлом.