Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Удаление элемента из файла


Автор: Компоратор 1.7.2007, 11:21
Есть тут у меня типизированный файл.
Пусть в него записывается какой-нибудь 
Код

Rec = packed record
     Rec1: integer;
     Rec2: integer;
end;


Тут вдруг встала колом задача - удаление произвольной записи. Никогда такого не делал. Юзаю обычный AssignFile без FileStream.

Мне думается, что нужно сдвигать все записи выше, только я догнать не могу - как это организовать.

Может кто что подскажет? Желательно с кодом.

Автор: Yanis 1.7.2007, 11:24
Как это как организовать?
Читаешь следующую запись после той которую надо удалить, передвигаешься на начало удаляемой записи и пишешь считанную и т.д.

Автор: Компоратор 3.7.2007, 05:27
Немного подправил пост...

Ок, вот небольшой примерчик (повторюсь - самый примитивный, без обработки исключений):

Код

type
    Rec = packed record
     Rec1: integer;
     Rec2: integer;
end;

Код

var
   RecBody: TRec;
   RecFile: file of TRec;
   I: integer;

Код

begin
            ...
while not EOF(RecFile) do
        begin
          Seek(RecFile,I+1);
          Read(RecFile,RecBody);
          Seek(RecFile,I);
          write(RecFile, RecBody);
          Inc(I);
        end;


Все удаляется, единственное, я еще не понял, как последнюю запись обрезать - она лишняя получается вроде.
 Есть такая штука - Truncate, как ей можно воспользоваться в данном случае?

Автор: Yanis 3.7.2007, 06:36
Цитата(Компоратор @  3.7.2007,  06:27 Найти цитируемый пост)
 Есть такая штука - Truncate, как ей можно воспользоваться в данном случае? 

Код
Seek(f, FileSize(f) - 1);
Truncate(f);

Автор: Компоратор 3.7.2007, 08:26
Вот итоговая процедура:

Код

  TRecBody = packed record
    Name: string[255];
    Password: string[255];
    Note: string[255];
  end;

Код

procedure TMainForm.DeleteItem;
{полное удалдение записи о пароле}
var
  RecBody: TRecBody;
  RecFile: file of TRecBody;
  I,J: integer;
begin
  AssignFile(RecFile,ExtractFilePath(Application.ExeName)+'\Content.rpd');
  Reset(RecFile);
  for J:=0 to ListBox.Count-1 do //элементы отображены в ListBox
  if ListBox.Selected[J] then // выбрали строку J
      begin
      Seek(RecFile,J);
      Read(RecFile,RecBody);
      if MessageDlg('Запись будет удалена',mtConfirmation,[mbOk,mbCancel],0) = mrOk
      then
      begin
        I:=J;
        while not EOF(RecFile) do //до конца файла
        begin
            {читаем следующий элемент
             и записываем в предыдущий...}
            Seek(RecFile,I+1);
            if not Eof(RecFile) then
            begin
              Read(RecFile,RecBody);
              Seek(RecFile,I);
              write(RecFile, RecBody);
              Inc(I);
            end;
        end;
        seek(RecFile, FileSize(RecFile)-1);
        Truncate(RecFile); //обрезаем нафиг конец у файла
      end;
        CloseFile(RecFile);
        Exit;
      end;
  CloseFile(RecFile);
end;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)