Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

  1. Add a bonus as int32 field to Score. Which numbers in the output change?
  2. Write record 6 with PutRecord, then print Count( ) and record 5.