Updating a Random-Access File
Credit: Luther Blissett
Problem
You want to read a binary record from somewhere inside a large file of fixed-length records, change the values, and write the record back.
Solution
Read the record, unpack it, perform whatever computations you need for the update, pack the fields back into the record, seek to the start of the record again, and write it back. Phew. Faster to code than to say:
import struct
thefile = open('somebinfile', 'r+b')
record_size = struct.calcsize(format_string)
thefile.seek(record_size * record_number)
buffer = thefile.read(record_size)
fields = list(struct.unpack(format_string, buffer))
# Perform computations, suitably modifying fields, then:
buffer = struct.pack(format_string, *fields)
thefile.seek(record_size * record_number)
thefile.write(buffer)
thefile.close( )Discussion
This approach works only on files (generally binary ones) defined in
terms of records that are all the same, fixed size; it
doesn’t work on normal text files. Furthermore, the
size of each record must be that defined by a
struct’s format string, as shown
in the recipe’s code. A typical format string, for
example, might be "8l", to specify that each
record is made up of eight four-byte integers, each to be interpreted
as a signed value and unpacked into a Python int.
In this case, the fields variable in the recipe
would be bound to a list of eight ints. Note that
struct.unpack returns a tuple. Because tuples are immutable, the computation would have to rebind ...