Binary & Random-Access Files
A RANDOM file is an array of equal-sized records on disk; you can read or write record *n* directly without reading the records before it.
20.1 RANDOM files — fixed-length records
A RANDOM file is an array of equal-sized records on disk; you can read or write record *n* directly without reading the records before it.
LEN = LEN(p) sets the record length (all fields must be fixed size — use STRING * n).
PUT #f, recordNumber, variable writes; GET #f, recordNumber, variable reads (record numbers start at 1).
Omitting the record number uses the next record.
TYPE Product
id AS LONG
nm AS STRING * 20
price AS SINGLE
stock AS INTEGER
END TYPE
DIM p AS Product
OPEN "products.dat" FOR RANDOM AS #1 LEN = LEN(p)
' Write three records
p.id = 1: p.nm = "Keyboard": p.price = 29.99: p.stock = 15: PUT #1, 1, p
p.id = 2: p.nm = "Mouse": p.price = 14.5: p.stock = 40: PUT #1, 2, p
p.id = 3: p.nm = "Monitor": p.price = 189: p.stock = 7: PUT #1, 3, p
' Read record 2 directly
GET #1, 2, p
PRINT p.id; RTRIM$(p.nm); p.price; p.stock
' Update record 3 in place
GET #1, 3, p
p.stock = p.stock - 1
PUT #1, 3, p
PRINT "Number of records:"; LOF(1) \ LEN(p)
CLOSE #120.2 BINARY files — bytes at any position
Positions start at 1. SEEK #f, pos moves the file pointer; SEEK(f) returns it.
GET reads as many bytes as the variable's size; for a variable-length string, it reads LEN(s$) bytes — so pre-size it: s$ = SPACE$(100): GET #1, , s$.
Whole TYPEs and arrays elements can be PUT/GET in one statement.
DIM header AS STRING * 4, version AS INTEGER, count AS LONG
OPEN "save.bin" FOR BINARY AS #1
header = "SAV1": version = 2: count = 12345
PUT #1, 1, header ' bytes 1-4
PUT #1, , version ' next 2 bytes
PUT #1, , count ' next 4 bytes
CLOSE #1
OPEN "save.bin" FOR BINARY AS #1
GET #1, 1, header: GET #1, , version: GET #1, , count
PRINT header; version; count; " size:"; LOF(1); "bytes"
CLOSE #120.3 Reading a whole file quickly
OPEN "readme.txt" FOR BINARY AS #1
content$ = SPACE$(LOF(1))
GET #1, , content$
CLOSE #1
PRINT "Read"; LEN(content$); "bytes"20.4 Number-to-bytes conversion (legacy)
Before PUT could write numbers directly, programs converted them to strings:
MKI$(n%) / CVI(s$) INTEGER ↔ 2-byte string MKL$(n&) / CVL(s$) LONG ↔ 4-byte string MKS$(n!) / CVS(s$) SINGLE ↔ 4-byte string MKD$(n#) / CVD(s$) DOUBLE ↔ 8-byte string
These are also handy for packing binary network messages. Old FIELD #1, 20 AS N$, 4 AS P$ with LSET/RSET defined random-file buffers before TYPEs existed.
20.5 Choosing a file format
Text (PRINT #/LINE INPUT #) human-readable, editable, portable slower, must parse CSV (WRITE #/INPUT #) opens in spreadsheets quoting edge cases direct access to record n, in-place updates compact, fast, any layout not human-readable; byte order and type sizes matter between dialects
FreeBASIC: Open ... For Binary, Get #, Put # work the same (positions start at 1); Integer is 32/64-bit in FB, so declare file fields as Short/Long explicitly when sharing files with QBasic programs. VB.NET: FileStream, BinaryReader/BinaryWriter (ReadInt32, Write(value)), File.ReadAllBytes; structured data more often goes to JSON (System.Text.Json) or a database.