#deletion technique?
14 messages in this thread
Hi. I think this advice will have to come from some veteran programmer.
What I'm looking for is a method to erase a record from a file. I've
used fwrite to enter many struct records but what do I do if I want to
delete record number 3 for example? I know how to do random access to the
record but can only give the present values a zero or NULL in the case of
a string struct member. The problem is the empty structure still takes up
space and a record number in my file.
The only thing I can think of now is some difficult routine to resave
the file starting from the record to delete. Is there a better way?
Thanks in advance, Henry
Henry,
You're basically between a rock and a hard place, and, this is a common
programming problem. I'll tell you how'd I'd handle it and hopefully others
will jump in their solutions.
If your file will never be too large to fit into memory, I would create a
linked list of your records and as any record changes, write the list back out
to disk. That's the easy way.
Otherwise you'll have to do what you suggested … hit the records directly
(hopefully you've defined a non-public field called "deleted" or some such) and
set that record to deleted or NULL or whatever you want to use. This will
effectively get rid of the record but it's still in the file. You'll have to
write some routine (external program or part of your main program) to do clean
up on your master file and get rid of the deletes (read a record, if not
deleted, write it to a new file, repeat). The advantage to this is that when
you do clean up your file you can have a chance to again look over the deletes
and recover any if you need to.
-sja
To answer this question another way, there's no standard 'stdio' function that
will shorten a file's size. Few operating systems have such a function. Other
programs that need to do this sort of operation actually copy the true records
to a second file, skipping deleted records, then rename the files behind the
scenes so that the user thinks that the database file is now smaller.
I think you can "truncate" but not "compress".
DJ
On AP from Queens, the thrill and excitement of the Big Apple
Where a little paranoia keeps you healthy and sane …
Using which function?
This'll teach me to check my "internal reflexive messaging" more
thoroughly when tired. I must have been thinking of the TRUNCATE open
option, which actually truncates the whole file and is thus rather useless
for the desired effect. Sorry for the wasted energy.
DJ
On AP from Queens, the thrill and excitement of the Big Apple
Where a little paranoia keeps you healthy and sane …
That technique works best if you planned to delete all the records in the file.
🙂
I guess the key word here is "planned" 🙂
DJ
On AP from Queens, the thrill and excitement of the Big Apple
Where a little paranoia keeps you healthy and sane …
No, you can actually truncate.
Open the file with the fopen() function and give an open mode of "r+",
use fseek() to seek to the position you want to truncate the file at,
then fclose() the file.
–Doug
I was actually looking for something like that when I realized I wasn't so
sure about what I had written, but looking through the SAS 6.5 reference
did not point taht out. I specifically looked for that very thing, as it
rang a bell in my mind but thought it might be from a more obscure
language from my hoary past. Have you actually done this?
DJ
On AP from Queens, the thrill and excitement of the Big Apple
Where a little paranoia keeps you healthy and sane …
>> Have you actually done this?
You might look on page xi of the 6.50 Users Guide.
Steve, there's nothing there about truncating files – just a bunch of
names … DOHW!
OK, OK!! How was I supposed to know??!!! I take it that means yes :-).
BTW, Doug, thanks for a great compiler! And I guess I wasn't out of my
gourd.
DJ
On AP from Queens, the thrill and excitement of the Big Apple
Where a little paranoia keeps you healthy and sane …
The best method depends on how you are using the file.
Your method of resaving the file from the deleted record to the end will
work but if the file is long, (or medium size and on a floppy disc) it is
likely to be slow. A compromise method is to remember which records have
been deleted and do the rewrite once when the file is closed, but this is
more complex to program since you have to keep track of 'holes' in the
sequence of records before the file is saved.
Another method is to have a flag on each record which says whether the
record is used. To delete a record simple set it to 'not used'. Your
routines for accessing records will have to check if the flags are set.
When adding a new record don't go straight to the end of the file but
first look for a record set to 'not used'. This makes data access a bit
more tricky, and if the file grows large at any time it will never get
smaller again just from deleting records.
Peter Wade
Autopiloting from London, England