Учебник по Delphi

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

   В Delphi нет готовой процедуры для удаления записей из файла. Поэтому приходится придумывать способы сделать это. Я обычно использую следующий метод. Чтобы удалить запись из файла, нужно открыть еще один файл и скопировать в него по порядку все записи из первого файла, за исключением удаляемой. Затем файлы закрывают, и второй файл переименовывают, чтобы его имя стало как у первого. В следующем примере из файла out. dat удаляется пятая запись.

Листинг 8.20
procedure TForml.Button2CI ick(Sender: TObject);
var
F1: Fi le of Integer;
// файл, из которого удаляется запись
р: Integer;
F2: Fi le of Integer;
// временный файл
I : Integer;
begin

// открываем файл, из которого удаляется запись
AssignFile(F1,out.dat);
Reset(F1);

// создаем временный файл
AssignFi le(F2,temp);
Rewrite(F2);
i := -1;
// счетчик записей
// читаем каждую запись в цикле

whi le not Eof(F1) do
begin
Read(F1,p);
Inc(i);
// увеличиваем счетчик записей
// если запись не пятая, то выносим ее во временный файл

if i<>5 then Write(F2,p); ,
end;

// закрываем файлы
CloseFile(F2);
CloseFi le(F1);

// удаляем основной файл
Erase(F1);
// переименовываем временный файл в основной
Rename(F2,out.dat);
end;

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

Листинг 8.21
DelFile=record
рг: Boolean;
fio: String[200];
n: Integer;
end;

   Для обозначения того, удалена запись или нет, создано поле рг типа Boolean. При создании новой записи рг присваивается значение False. Это означает, что запись не удалена. Если ее нужно удалить, то рг просто присваивается True. Естественно, при работе с файлом нужно учитывать поле рг (если pr=True, то считать запись несуществующей). Остальные поля записи используются как обычно.

   В процессе работы записи просто помечаются как удаленные, а затем, по мере их накопления, выполняется какое-то действие (сжатие, индексация), вместе с которым уничтожаются помеченные записи.

   Кстати, именно так и удаляются записи практически во всех СУБД (системах управления базами данных). Положительная сторона данного метода еще и в том, что помеченные, но еще не удаленные окончательно записи можно восстановить! Такой метод удаления записей работает очень быстро независимо от размера файлов. Но это не совсем удаление, поэтому лучше использовать комбинацию этих двух методов.




 

Рейтинг@Mail.ru          Rambler's Top100

X-ZiBiT