При логическом удалении запись фактически не удаляется. Вместо этого используется специальный признак: активная/пассивная запись. Логическое удаление – установка признака в состояние "пассивная". При этом запись не стирается. Во время обработки файла проверяется признак, и обрабатываются только активные записи.
Пример.В файле Ftel некоторые номера телефонов сняты. Для логического удаления необходимо добавить в запись Tel еще одно поле, например:
При создании файла Ftel поле Actвсех записей имеет значение True – запись "активна" (не удалена), т.е. программа при начальном заполнении будет содержать такой фрагмент:
{Начальное заполнение}
Assign (Ftel,’tsprav’);
Rewrite(Ftel);
With Rtel do
Begin
Nom := 0;
Fam := ’’;
Adr := ’’;
Act := True;
end;
For k:=0 to n do
Begin
Seek(ftel,k);
Write(Ftel,Rtel);
end;
Удаление записи с номером Numвыполняется как коррекция (изменяется содержимое поля Act на противоположное):
Writeln(’Введите удаляемый номер телефона’);
Read(num);
Seek(Ftel,num);
Read(Ftel,Rtel); {Указатель перешел к следующей записи: num+1}
Rtel.Act := False;
Seek(Ftel,num); { Вернем указатель к записи num }
Write(Ftel,Rtel);
При обработке файла в этом случае необходима дополнительная проверка наличия (активности) записи:
Seek(Ftel,k);
If Not Eof(Ftel) then
Begin
Read(Ftel,Rtel);
if Rtel.Act then {Запись не удалена}
Begin
.....{ обработка неудаленной записи }
end;
......
end;
При физическом удалении записи на ее место переписывается новая информация, т.е. запись стирается. Эта операция выполняется по схеме, приведенной на рис. 2.12, где показано удаление записи с номером 1.
Составим процедуру удаления записи с заданным номером Num из файла f. Нужно учесть, что удаление сводится к переписи записей после номера Num на 1 место вперед. После переписи (или если для удаления сразу была назначена последняя запись), файл нужно урезать с помощью процедуры Truncate и таким образом убрать из него последнюю запись. Напомним, что после выполнения операций записи/чтения текущая позиция в файле перемещается к следующему элементу.
Считаем, что в программе описан тип Ft = File Of Zap.В процедуре используется функция FileSize(имя_файла), возвращающая размер файла. Описание этой функции приведено в следующем пункте (21.2.5).
Procedure RemoveF(Num : Integer; Var F : Ft);
{Удаление записи с номером num из файла f}
Var
K : Integer;
R : Zap;
Begin
If num<FileSize(f)-1 then {Удаляемая запись не последняя}
begin
K := num; {номер записи, в которую будем переписывать данные}