Удаление записей из файла
Эта операция может быть двух типов: а) логическое удаление; б) физическое удаление. При логическом удалении запись фактически не удаляется. Вместо этого используется специальный признак: активная/пассивная запись. Логическое удаление – установка признака в состояние " пассивная". При этом запись не стирается. Во время обработки файла проверяется признак, и обрабатываются только активные записи. Пример. В файле Ftel некоторые номера телефонов сняты. Для логического удаления необходимо добавить в запись Tel еще одно поле, например: Type Tel = Record Nom = Integer; Fam, Adr: String[15]; Act: Boolean; {Признак активная/пассивная (удаленная)} end; При создании файла 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; {номер записи, в которую будем переписывать данные} {Перепись записей на 1 вперед – в начало f} Seek(f, k+1); {Следующая после удаляемой запись} While not eof(f) do Begin Read(f, R); Seek(f, k); {Возврат назад } Write (f, R); k: =k+1; Seek (f, k+1); end; end; {Урезаем файл f по последней записи} Seek(f, FileSize(f)-1); Truncate(f); Close(f); end;
|