Читаем Фундаментальные алгоритмы и структуры данных в Delphi полностью

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

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

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

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

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

Существует два возможных решения для организации удаления записей. Первое - самое простое, которое используется в файлах данных dBASE. Для каждой записи в файле устанавливается префикс, состоящий из одного байта и содержащий флаг удаления. Флаг может быть булевым значением (true/fasle) или символом (например, 'Y'/'N' или '*'/пусто). При удалении записи устанавливается флаг удаления, который и будет говорить о том, что данная запись удалена. Все кажется достаточно простым, но что делать с удаленными записями? Вариант А - просто игнорировать. К сожалению, в этом случае в файле будет накапливаться все большее и большее число удаленных записей и в некоторый момент времени файл придется уплотнять, дабы избавиться от ненужных записей и уменьшить размер файла данных. Вариант В - повторно использовать место, занимаемое удаленными записями. При добавлении в файл новой записи по файлу выполняется поиск удаленной записи, на место которой и будет добавлена новая запись. Очевидно, что вариант В неэффективен. Представьте себе, что в файле, содержащем 10000 записей, удалена только одна запись. Для того чтобы найти всего одну удаленную запись, нам придется выполнить цикл, по крайней мере, по 5000 записям. Эта операция принадлежит к классу О(n), поэтому вариант В лучше не реализовывать.

Тем не менее, вариант В имеет и свои положительные стороны, в частности, повторное использование места, занимаемого удаленными записями. Если бы только нам удалось привести его к классу O(1)! Такие рассуждения привели к разработке еще одного метода удаления записей - цепочке уделенных записей (для этого метода наличие служебного блока данных обязательно, поэтому будем считать, что служебные данные присутствуют).

Перед каждой записью находится 4-байтный префикс - значение типа longint. Он предназначен для хранения флага удаления. Его нормальное значение -1 - значение, которое указывает, что запись не удалена. Любое другое значение будет означать, что запись удалена. Но это еще не все. Обратите внимание, что размер каждой записи увеличивается на 4 байта. В свою очередь, пользователь считает, что размер записи не изменился. В служебном заголовке хранится еще одно значение типа longint, которое представляет собой порядковый номер первой удаленной записи. Нормальное значение для этого поля -2, которое означает, что в файле нет удаленных записей.

Рисунок 2.3. Удаление записи

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных