Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Информатика программирование, учебник.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
22.08 Mб
Скачать

Удаление записи из файла

Удаление записей происходит в два этапа. На первом этапе запись помечается как удаляемая. Для этого в записи предусматривается специальное поле DEL: BYTE, занимающее один байт памяти. При пометке записи на удаление в нее заносится специальный код, например, $FF. Таким образом, удаленные записи физически продолжают существовать еще какое-то время. Как правило, при просмотре файла они высвечиваются с пометкой Delete. Если пользователь базы данных обнаружил, что напрасно хочет удалить ту или иную запись он может ее восстановить, повторной пометкой записи на удаление.

На втором этапе происходит физическое удаление записей помеченных как удаляемые. Этот процесс называется сжатием файла. Создается рабочий файл TEMP структура которого тождественна сжимаемому. Основной файл просматривается с первой записи до последней. Каждая запись основного файла проверяется на признак “удалена” DEL = $FF. Если это условие не выполнено, то текущая запись копируется в файл TEMP. Таким образом, когда мы достигнем метки EOF основного файла все непомеченные на удаление записи этого файла будут скопированы в рабочий файл. Теперь следует удалить основной файл с помощью процедуры Erase. А файлу TEMP присвоить имя основного файла с помощью процедуры Rename.

Пример 9. Требуется разработать программу, обеспечивающую последовательный просмотр и пометку удаляемых записей в файле STUDENTS.DAT с помощью поля - DEL: BYTE, а также сжатие файла, если это нужно пользователю.

PROGRAM PR9;

USES CRT;

Type STUDENT = record

tab : Longint;

Fio : String[15];

Data : String[8];

Grup : String[7];

Stepa: Real;

DEL: BYTE;

DATE: STRING[8]

end; {RECORD}

Var S:STUDENT; St: String;CH, CH1: CHAR;

Fs, Fi: File of STUDENT; NZ: WORD;

FUNCTION DL(X: BYTE): STRING;

BEGIN

DL := ' ';

IF X = $FF THEN DL := 'DELETE'

END; {FUNCTION}

Begin

Writeln('Введите имя основного файла: '); Readln(St);

Assign (Fs, St); Reset(Fs); {открытие основного файла}

WRITELN('Используйте клавиши:');

WRITELN('ESC - завершение работы с записями файла;');

WRITELN('ENTER - переход к следующей записи;');

WRITELN('DEL - пометка записи на удаление, отмена признака;');

WRITELN('Пробел - повторный вывод записи;');

WRITELN('HOME - первая запись в файле;');

WRITELN('Стрелка вверх - предыдущая запись.');

While Not Eof(Fs) {Просмотр основного файла}

Do begin

NZ := FILEPOS(Fs); {Запомнить номер текущей записи}

Read(Fs, S);

WRITELN(NZ:2, S.TAB:9, S.FIO:17, S.Data:10, S.Grup:9,

S.STEPA:9:2, DL(S.DEL):8);

CH:=' ';CH1:=' '; CH := READKEY; {Ожидание нажатия клавиши}

IF ORD(CH) = 0

THEN BEGIN CH1:=READKEY;{КЛАВИШИ ВТОРОЙ ГРУППЫ}

CASE ORD(CH1) of

83: BEGIN

IF S.DEL = $FF {НАЖАТА КЛАВИША: DEL}

THEN S.DEL:= $00 {ОТМЕНА УДПЕНИЯ}

ELSE S.DEL:= $FF; {ПОМЕТКА ЗАПИСИ НА УДАЛЕНИЕ}

SEEK(Fs, NZ);

WRITE(FS,S) {ЗАПИСЬ ОТМЕТКИ В ФАЙЛ}

END;

72: IF NZ=0 {НАЖАТА КЛАВИША: Стрелка вверх}

THEN SEEK(Fs, NZ) {ПЕРВАЯ ЗАПИСЬ }

ELSE SEEK(Fs, NZ-1);{НА ПРЕДЫДУЩУЮ ЗАПИСЬ }

71: SEEK(Fs,0) {НАЖАТА КЛАВИША: HOME }

END {CASE}

END {THEN}

ELSE CASE ORD(CH) of {КЛАВИШИ ПЕРВОЙ ГРУППЫ}

13: CONTINUE; {НАЖАТА КЛАВИША: ENTER}

27: BREAK; {НАЖАТА КЛАВИША: ESC }

32: SEEK(Fs,NZ) {НАЖАТА КЛАВИША: ПРОБЕЛ}

END; {CASE}

END; {WHILE}

WRITELN ('БУДЕТЕ СЖИМАТЬ ФАЙЛ: Y - ДА'); READLN(CH);

IF (CH = 'y') OR (CH = 'Y')

THEN BEGIN

Assign(Fi,'A:\TEMP'); Rewrite(Fi); {СОЗДАНИЕ РАБОЧЕГО НАБОРА}

SEEK(Fs,0);

While Not Eof(FS) {ПРОСМОТР ОСНОВНОГО ФАЙЛА}

Do begin

Read(Fs, S);

IF S.DEL <> $FF

THEN WRITE(FI, S) {ПРОПУСК ПОМЕЧЕННЫХ ЗАПИСЕЙ}

END;

Close(Fs);

ERASE(Fs); {УДАЛЕНИЕ ОСНОВНОГО ФАЙЛА}

Close(Fi);

RENAME(Fi,St) {РАБОЧИЙ НАБОР ПЕРЕИМЕНОВЫВАЕТСЯ В ОСНОВНОЙ}

END

END.