Solved

Deleting Records

Posted on 1998-12-14
9
179 Views
Last Modified: 2010-04-16
I can't work out the code for deleting and searching for records in random accsess files. I am using borlands |Turbo Pacal for windows 1.5. Ten points are up for grabbs from me, so be quick.
0
Comment
Question by:Austin120998
9 Comments
 
LVL 3

Expert Comment

by:vikiing
ID: 1216504
As long as I know, you can not delete records from a random file; the only thing you can do is to "pack" the file, by moving records one space in order to overwrite the record you want to remove with something like this:

{ N = record number of record to be erased
  MaxRec = quantity of records in file }

For i:=n to MaxRec-1 do begin
    Seek(thisfile, i+1); Read(thisfile, thisrec);
    Seek(thisfile, i); Write(thisfile, thisrec);
end;

0
 
LVL 3

Expert Comment

by:vikiing
ID: 1216505
As long as I know, you can not delete records from a random file; the only thing you can do is to "pack" the file, by moving records one space in order to overwrite the record you want to remove with something like this:

N = record number of record to be erased
MaxRec = quantity of records in file

For i:=n to MaxRec-1 do begin
    Seek(thisfile, i+1); Read(thisfile, thisrec);
    Seek(thisfile, i); Write(thisfile, thisrec);
end;

After completion of that, last two records will be duplicated. Notice the file size remains THE SAME, because you don't have way to reclaim the space of the so deleted record. To have a scheme like this, you need to store the ACTUAL MaxRec into some portion of the file itself (record #0 is often used for that purpose), mainly because it's value can't be taken from Filesize().

0
 
LVL 3

Expert Comment

by:vikiing
ID: 1216506
How  I  H-A-T-E when an answer goes twice... ~~~~~~>:(

0
 
LVL 3

Expert Comment

by:vikiing
ID: 1216507
As long as I know, you can not delete records from a random file; the only thing you can do is to "pack" the file, by moving records one space in order to overwrite the record you want to remove with something like this:

N = record number of record to be erased
MaxRec = quantity of records in file

For i:=n to MaxRec-1 do begin
    Seek(thisfile, i+1); Read(thisfile, thisrec);
    Seek(thisfile, i); Write(thisfile, thisrec);
end;

After completion of that, last two records will be duplicated. Notice the file size remains THE SAME, because you don't have way to reclaim the space of the so deleted record. To have a scheme like this, you need to store the ACTUAL MaxRec into some portion of the file itself (record #0 is often used for that purpose), mainly because it's value can't be taken from Filesize().

0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 2

Expert Comment

by:kellyjj
ID: 1216508
Another way to do it is to make a field in the record that indicates its status (deleted,used..). For example, -1 could mean deleted and 1 could mean deleted.

This would mean only have to change one field, plus, when write out new records, you can use the space being occupied by deleted records.
0
 
LVL 3

Expert Comment

by:vikiing
ID: 1216509
Kellyjj: the problem of doing the way you suggest is that if you use a special search algorithm (i.e. a binary search), where records MUST be sorted, you must sort ALL records, no matter they have been logically deleted or not, with increase of process time.

Even a sequential search will have to check each record read to see if flag is present. Of course, it surely works; but I don't like it... :)
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 1216510
hi austin,

this is delphi code (full applcation with insert update delete next prev (not perfect!)), but you can pick out parts. i recommend that the file is unsorted, therefore i pick by deleting a record the last record in the file and write over the record which want to delete, then i go to the lastrecord and truncate there the file.


unit r_file_u;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    BInsert: TButton;
    BUpdate: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    BPrev: TButton;
    BNext: TButton;
    BDelete: TButton;
    procedure FormCreate(Sender: TObject);
    procedure BInsertClick(Sender: TObject);
    procedure BUpdateClick(Sender: TObject);
    procedure BDeleteClick(Sender: TObject);
    procedure BNextClick(Sender: TObject);
    procedure BPrevClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

Type TheRec = Record
                Name1 : String[100];
                Name2 : String[100];
              end;
Var
  f : file of TheRec;
  r : TheRec;   {Buffer}
  cr : LongInt; {FileCursor}
  rc : LongInt; {RecordCount}
  tc : LongInt; {TempFileCursor}

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  assignfile(f,'MyFile.Dat');
  if not(fileexists('MyFile.Dat')) then
    rewrite(f)
  else
    reset(f);
  cr := 0;
  rc := fileSize(f) div sizeof(therec);
end;

procedure TForm1.BInsertClick(Sender: TObject);
begin
  r.name1 := edit1.Text;
  r.name2 := edit2.Text;
  seek(f,rc);
  write(f,r);
  inc(rc);
  cr := rc;
end;

procedure TForm1.BUpdateClick(Sender: TObject);
begin
  if cr > 0 then
  begin
    seek(f,cr-1);
    write(f,r);
  end;
end;

procedure TForm1.BDeleteClick(Sender: TObject);
begin
  if rc > 0 then      {Are there record in}
  begin
    if cr <> rc then  {CurrentCursor is not LastRecord }
    begin
      seek(f,rc-1);   {Goto LastRecord}
      read(f,r);      {Buffer LastRecord}
      seek(f,cr-1);   {Goto Record to deleted}
      write(f,r);     {Paste over LastRecord}
    end
    else              {The Record to delete is LastRecord}
    begin
      if rc > 1 then    {More then one Record}
      begin
        seek(f,rc - 2); {Goto the Record before LastRecord}
        read(f,r);      {Read for Output}
        cr := rc - 1;   {set CurrentCursor to Record before LastRecord}
      end
      else
      begin             {Last Record will be deleted : File then empty }
        r.Name1 := '';
        r.Name2 := '';
        cr := 0;
      end;
    end;
    seek(f,rc-1);     {Goto LastRecord}
    truncate(f);      {Truncate the file here}
    edit1.text := r.name1;  {Output }
    edit2.text := r.Name2;
    dec(rc);
  end;
end;

procedure TForm1.BNextClick(Sender: TObject);
begin
  if cr < rc then
  begin
    read(f,r);
    inc(cr);
    edit1.text := r.name1;
    edit2.text := r.Name2;
  end;
end;

procedure TForm1.BPrevClick(Sender: TObject);
begin
  if cr > 1 then
  begin
    seek(f,cr-2);
    read(f,r);
    dec(cr);
    edit1.text := r.name1;
    edit2.text := r.Name2;
  end;

end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  closefile(f);
end;

end.



meikl
0
 
LVL 1

Accepted Solution

by:
bobbyo earned 10 total points
ID: 1216511
Basically what this does is copies all records except for the one you want to delete to a new file the renames it to the previous file.

Code:

Uses Crt;

Type DataRecord = Record
     Name : String;
     Surname : String;
     End;

Var
   OldFile,NewFile : File Of DataRecord;
   TheRecord : DataRecord;
   DeleteWhichRecord : Word;
   Loop1 : Word;

Begin
   Writeln('Enter record number you want to delete : ');
   Readln(DeleteWhichRecord);
   Assign(OldFIle,'DATA.DAT');
   Assign(NewFile,'TEMPDATA.DAT');
   Reset(OldFile);
   Rewrite(NewFile);
   For Loop1 := 1 To FileSize(OldFile) Do
   Begin
      Read(OldFile,TheRecord);
      If Loop1 <> DeleteWhichRecord Then
         Write(NewFile,TheRecord);
   End;
   Close(OldFIle);
   CLose(NewFile);
   Erase(OldFile);
   Rename(NewFile,'DATA.DAT');

End.
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 1216512
hi bobbyo,

you read your file by byte, not by record, your destination becomes shradder. On great files it will take time for deleting one record.

meikl
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
WSAAdressToString example Delphi code needed 3 1,761
Capture cookies with delphi 5 1,005
How to load a ClientDataSet in Delphi from a Resource file? 4 1,290
audio record to file 4 1,059
When we talk about DevOps toolchains, I sometimes wonder how many people really get what we’re talking about. I don’t know if it’s just semantics or tone or something else, but sometimes I think it just sounds like buzzword sausage. So it’s always …
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
Hi friends,  in this video  I'll show you how new windows 10 user can learn the using of windows 10. Thank you.

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

25 Experts available now in Live!

Get 1:1 Help Now