Большой архив статей, книг, документации по программированию, вебдизайну, компьютерной графике, сетям, операционным системам и многому другому
 
<Добавить в Избранное>    <Сделать стартовой>    <Реклама на сайте>    <Контакты>
  Главная Документация Программы Обои   Экспорт RSS E-Books
 
 

   Интернет технологии -> Perl -> PERL Вопросы и ответы ( FAQ )


FAQ по PERL

8. БД на плоских файлах

8.1 Я хочу какую-нибудь простейшую БД и прямо сейчас!

Вы можете использовать простой текстовый файл с разделителями. Например, если мы пишем нечто типа телефонной книги, то вполне вероятно предположить, что ни в чьем имени, ни в номере телефона не встретится последовательность ::, так что именно ее и можно использовать в качестве разделителей.

Файл с данными может выглядеть так:

phones.data
Иванов И.И.::888-0000::Какая-то улица, 17, кв 40
Сидоров П.И.::888-8429::Другая улица, 5, кв 21
...... и тд.

тогда программа, которая читает данные, может быть примерно такого вида:

dump_phones.pl
#!/usr/bin/perl
$filename = 'phones.data';
# открываем файл
open DATA, $filename or die "Невозможно открыть $filename: $!";

# читаем построчно из файла
while (<DATA>) {
        chomp; # удаление символа конца строки
        # теперь в $_ есть строка и мы ее разделяем на переменные
        ($name, $phone, $address) = split(/::/);
        # и выведем на печать
        print "Имя: $name, телефон: $phone, адрес: $address\n";
}
close DATA;

Больше проблем возникает в случае, если надо удалить или отредактировать запись, но и их можно довольно просто и элегантно решить, если использовать механизм редактирования на месте (inplace edit) -- при использовании операции "ромб"(<>), можно читать из одного файла, а писать в другой:

change_phones.pl
#!/usr/bin/perl
$^I = '~'; # запускаем inplace edit
while (<>) { # Обратите внимание, что мы не открывали файл: при такой
        #конструкции имя файла берется из командной строки
        chomp;
        ($name, $phone, $address) = split(/::/);
        if (.... некоторое условие, при котором мы оставляем наши данные ... )
        {
                print "$name::$phone::$address\n"; # теперь данные есть в новом файле
        }
}

если запустить это программу как

change_phones.pl phones.data,

то в текущем каталоге будут два файла: phones.data, с записями, которые удовлетворили нашим условиям и phones.data -- предыдущая копия.

Также, во многих случаях, всю программу такого типа можно записать как one-liner:

perl -i~ -n -e 'print if(... условие)'

Двоичные файлы

Для чтения двоичных файлов в Perl можно использовать функции read и unpack. К примеру, если использовать двоичный файл для хранения телефонной книги такого формата:

40 символов -- фамилия, И.О.

10 символов -- номер телефона,

60 символов -- адрес,

то строка описания формата для unpack будет выглядеть так:

$format_str = 'A40 A10 A60'

, а сама программа, аналогичная первому примеру:

binary_phones.pl
#!/usr/bin/perl
$format_str = 'A40 A10 A60';
open DATA, 'binary.dat' or die "$!";
while (read(DATA, $buf, 40+10+60)) { # <DATA> не покатит: такая
# конструкция будет читать до символа перевода строки, а это не то, что нужно
        ($name, $phone, $address) = unpack($format_str, $buf);
        # Теперь в $name, $phone, $address есть данные и с ними можно делать
        # все, что захочется
}
close DATA;

Чтобы вывести в файл такую запись можно использовать конструкцию типа

print FILE pack($format_str, $name, $phone, $address);

8.2 Можно ли как-нибудь из Perl получить доступ к dbf файлам?

Да, можно. На http://www.fi.muni.cz/~adelton/ есть модуль XBase, который позволяет читать/писать dbf. При чтении он даже поддерживает индексы. Кроме того, в комплект поставки также входит модуль DBD::XBase, при помощи которого можно оперировать dbf на SQL (более подробно про DBI -- далее).

8.3 А к MS access .mdb?

К файлам MS Access нельзя обращаться из perl напрямую, по крайней мере, в настоящее время.

К MS Access можно обращаться по ODBC, при помощи DBD::ODBC.

8.4 Зачем и как нужно запирать (lock) файлы?

Представьте себе ситуацию когда одновременно работают несколько копий одной и той же программы (к примеру, cgi-скрипты, обслуживающие запросы), читающие/пишущие в один файл, тогда рано или поздно возникнет ситуация при которой один скрипт прочитал данные, произвел над ними некоторые действия и собрался записать их назад в файл, но в это же время другой скрипт тоже прочитал данные, тоже произвел над ними действия, но (!) он прочитал старые данные, которые он и запишет поверх данных, выданных другим скриптом. Таким образом, в файле останутся данные записанные одним из скриптов -- в лучшем случае, в худшем -- структура файла будет испорчена. Чтобы этого избежать в Unix и большинстве других ОС есть системный вызов flock(2) или аналогичный.

Как использовать flock

К примеру, скрипт который записывает имена вызывающих хостов в файл. (На деле такой список, конечно, можно получить из журнала регистрации web-сервера).

lock_exm.pl
#!/usr/bin/perl
use Fcntl; # Импорт констант
open (HOSTS, '>>hosts.log'); # Файл открыт для добавления записи
flock(HOSTS, LOCK_EX);
# Теперь файл заблокирован: Если любой другой скрипт тоже вызовет flock на
# этом файле, его flock не вернет управление в программу, пока мы не
# разблокируем файл. Обратите внимание: flock -- декларативная функция, если
# один из скриптов ее не использует при записи, то вся ваша блокировка не
# работает.
print HOSTS $ENV{REMOTE_HOST}, "\n"; # записали строку
close HOSTS; # Файл при закрытии разблокируется автоматически

# Вывести сообщение для пользователей
print "Content-Type: text/plain\n\n";
print "Название вашего хоста записано\n";

Более подробный рассказ о flock и пример доступны на http://w3.stonehenge.com/merlyn/WebTechniques/col04.html

8.5 Чего делать на системах

Судя по perlfaq5(1), можно использовать модуль File::Lock с CPAN.

[   ОГЛАВЛЕНИЕ   ]


 

 
Интересное в сети
 
10 новых программ
CodeLobster PHP Edition 3.7.2
WinToFlash 0.7.0008
Free Video to Flash Converter 4.7.24
Total Commander v7.55
aTunes 2.0.1
Process Explorer v12.04
Backup42 v3.0
Predator 2.0.1
FastStone Image Viewer 4.1
Process Lasso 3.70.4
FastStone Image Viewer 4.0
Xion Audio Player 1.0.125
Notepad GNU v.2.2.8.7.7
K-Lite Codec Pack 5.3.0 Full


Наши сервисы
Рассылка новостей. Подпишитесь на рассылку сейчас и вы всегда будете в курсе последних событий в мире информационных технологий.
Новостные информеры. Поставьте наши информеры к себе и у вас на сайте появится дополнительный постоянно обновляемый раздел.
Добавление статей. Если вы являетесь автором статьи или обзора на тему ИТ присылайте материал нам, мы с удовольствием опубликуем его у себя на сайте.
Реклама на сайте. Размещая рекламу у нас, вы получите новых посетителей, которые могут стать вашими клиентами.
 
Это интересно
 

Copyright © CompDoc.Ru
При цитировании и перепечатке ссылка на www.compdoc.ru обязательна. Карта сайта.