Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 [ 74 ] 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122

Чтобы удалить записи из базы данных, примените одну из функций splice, pop или shift к массиву @PH0KEL1ST, а затем запишите содержимое этого массива в файл. Кроме того, содержимое массива можно отредактировать, например с помощью функции grep, выполнив перебор элементов в цикле:

ePHOllELlST=redcldata(); I Шуестигъ все запжи базы данЕюх

I в гвсияв §PHONELIST t VpawM. все эгиунны, илсье шияиюгся ш "Анн" PHONELIST=grep(! /W, SPHOSELIST); writedata{ePHONELIST);

В этом примере все записи базы данных сначала копируются с помощью функции readdataO из файла в массив gPHONELIST. Затем с немощью функции grep проверяется, не содержат ли элементы массива строку Анн. Те элементы, в которгх такая строка не найдена, снова присваиваются массиву И в конце этот массив записывает-

ся в файл с помощью функции writedata (}.

Произвольный доступ к файлу

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

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

Открытие файлов для чтения и записи

До сих пор мы говорили о трех методах открытия файлов - для чтения, записи и

добавления информации в конец файла. Кроме того, файлы можно открывать одновременно и для чтения, и для записи. Возможные режимы открытия файлов перечислены в табл. 15.1.

Таблицу 1. Возможные режимы открытия файлов

Команд open

Чтение

Запись

Добавление

Создается при необходимости

Старые данные теряются

open{F, "<file")

open(F, "file")

open{F, >file--)

open(F, "»fib")

open(F, "+<filr")

open(F, "+>file")

open{F, »+»fiLe")



А теперь несколько замечаний.

• По возможности следует избегать использования режимов, при которых информация добавляется в конец файла. В некоторых системах, в частности в

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

• Никогда не следует использовать режим +>, поскольку при открытии файла его содержимое всегда стирается.

Перемещение по файлу при выполнении операции чтения или записи

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

Текущий указатель

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

Текущий указатель

Для перемещения текущего указателя в произвольное место файла используется функция seek. Она имеет три аргумента: первый - дескриптор открытого файла, второй - смещение в файле, определяющее новое положение текущего указателя. Последний аргумент определяет относительное положение указанного смещения: Q - относительно начала файла, 1 - относительно текущей позиции указателя файла, 2 - относительно конца файла. Ниже приведено несколько примеров использования функции seek().

t Опываа! с5(11ЭЗт:Ч(ИЧй айп для чяетия и запжи

cpai{F, "+<file.txt") II die "Оиибкаrpiсгпьпия file.txt: Si";

seek{F,0,2); I Гавщася в конец айга

pEcint F "Это ycxs\ файла"; \ Дабанм тают в изн файга

seek(F,0,0); т П=р=м=чррмп;т r тчялп фчйпя

print F "Это шгалэ файт"; * Дабанм тензт в штлэ файга

Чтобы узнать текущую позицию указателя в файле, используется функция tell. Например, после выполнения фрагмента предыдущего кода функция вернет

значение 16 (длина строка то начало файла"). Так происходит потому, что указатель располагается в файле сразу за последней порцией выведенных данных.




В этом разделе мы только поверхностно коснулись функций seek, tell и open, предназначенных для работы с файлами с произвольным доступом. За более подробной информацией обращайтесь к электронной документации. Перечисленные выше функции описаны в разделе perlfunc документации по Perl. Для доступа к нему введите команду perldoc perlfunc. Кроме того, дополнительную информацию по использованию функции open можно найти в разделе perlopentut документации по Perl. Для доступа к нему введите команду perldoc perlopentut.

Блокировка данных

Представьте себе, что вы написали на замечательную программу, которой будут пользоваться многие и многие люди. Независимо от того, в какой операционной

системе вы планируете ее эксплуатировать (UNIX, Windows NT или даже Windows 9x), возможны ситуации, когда несколько человек попытаются одновременно запустить вашу программу. А если вы предполагаете поместить программу на Web-сервер, она может запускаться так часто, что в памяти вообще одновременно будет находиться несколько копий программы.

А теперь предположим, что вашей программе для работы необходимы данные, хранящиеся, например, в текстовом файле, который б]л описан выше. Тип файла данных здесь не играет особой роли, поскольку все сказанное ниже можно применить к любому типу баз данных. Рассмотрим приведенный ниже фрагмент кода, в котором используются функции, описанные в предыдущем разделе.

chomp ($newrecord=<STDIN>); ePHONEL=readdata(); push(«PHONEL, Snewrecord}; writedata(ePHONEL);

Введем запись с клавиатуры Загрузим данные в массив gPHOKEL Поместим запись в массив

Запишем массив в файл

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

Время

1 2 3 4

Пользователь 1

5newrecord="flHHTpHu 1212"; iPRONElFreaddataO; puah(SPHONEL,$newrecord); writedata(iPHOHEL);

Пользователь 2

$пе«гесогй=*Юрий 555-6611"; iPHONEL=readdata()! push (iPHONEi., Snewrecord); writedata(ePHONEL);

С точки зрения нервого нользователя, данные читаются на втором шаге, новая запись Дмитрий 555-1212" добавляется в массив 8PH0NEL на третьем шаге, а на четвертом шаге содержимое массива записывается в файл базы данных.

С точки зрения второго пользователя, данные читаются на третьем шаге, новая запись "Кш 555-ббИ" добавляется в массив §PHONEL на четвертом шаге, а на пятом шаге содержимое массива записывается в файл базы данных.

Ошибка здесь вот в чем: данные, которые читает второй пользователь на третьем шаге, не содержат записи "Дмитрий 555-1212", поскольку первый пользователь еще не успел ее добавить в файл. Таким образом, второй пользователь добавляет запись "Юрий

15-й час. Обработка дах в



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 [ 74 ] 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122