Records at a position
A file of fixed-size records can be read and changed by record number,
without touching the records around the one you want. A
RecordFile( of T ) is such a file, holding records of the type T.
#import "std/fs"
print "Records at a position"
type Score
player as int32
points as int32
end type
dim as ustring dir_ = fs.CreateTempDir( "tbe" ).Value( )
dim as fs.RecordFile( of Score ) scores
'' Read and write, and created if it is missing.
scores.Open( fs.PathJoin( dir_, "scores.dat" ) )
dim s as Score
for n as int32 = 1 to 4
s.player = n
s.points = n * 100
scores.Append( s ) '' returns the new record's number
next
print "records:"; scores.Count( ).Value( ); _
", each"; scores.RecordLength( ); " bytes"
'' Straight to record 3, change it, write it back in place.
scores.GetRecord( 3, s )
s.points += 5
scores.PutRecord( 3, s )
for each r in scores '' each a Result, in record order
print "player"; r.Value( ).player; ":"; r.Value( ).points
next
'' There is no record 9: the value is false, and s is left as it was.
print "record 9 there? "; scores.GetRecord( 9, s ).Value( )
scores.Close( )
fs.RemoveDirAll( dir_ )
Output
Records at a position
records: 4, each 8 bytes
player 1: 100
player 2: 200
player 3: 305
player 4: 400
record 9 there? false
Open( path ) opens the file for reading and writing, and creates it if it is
not there. Records are numbered from 1. Append adds a record after the
last one and returns its number; PutRecord( n, s ) writes record n and
GetRecord( n, s ) reads it. Count( ) is the number of whole records, and
for each walks them in order, one Result per record.
Reading a record that is not all there, past the end or a short last record,
is not an error: the value is false and the record is left as it was.
Writing past the end grows the file, and the records in the gap read as zeros.
The record must hold only fixed-size fields: numbers, zstring * n, and types
made of those. A ustring is a pointer to its text, and a pointer written to a
file means nothing when it is read back. The bytes are the record's bytes in
memory, so add field = 1 to the type for a layout with no padding.
Underneath, these are ReadAt and WriteAt, which read and write bytes at a
byte position in any File without moving its position. Use them directly for
a file that mixes records with other data, such as a header, and
ReadRecord( of T ), WriteRecord( of T ) and RecordCount( of T ) for
records in a File you opened yourself.
Activities
- Add a
bonus as int32field toScore. Which numbers in the output change? - Write record 6 with
PutRecord, then printCount( )and record 5.