Random access reads and writes a file in BINARY mode. Random access records are stored differently from sequential access records. A random access record has a fixed length as does each field within the record. The fixed length determines the beginning and end of each record or field.
Syntax:OPEN fName FOR BINARY [NEW] AS hFile RECLEN RecordSize Parameters:
|
If RecordSize is a TYPE structure, RECLEN will calculate automatically the size of the TYPE structure.
If RecordSize is an INTEGER variable or a literal number, that integer must specify the fixed size of the random access record.
👉 If RecordSize is an INTEGER variable, it must be appended with integer data type signifier.
RecordSize is calculated before the value is passed to RECLEN. The programmer is responsible for determining the fixed size of the record.
Two main keywords are used in random access, RECLEN and RECORD.
RECLEN is used at the end of an OPEN file statement to calculate the fixed length of the random access record.
Syntax:OPEN fName FOR BINARY [NEW] AS hFile RECLEN RecordSize Parameters:
|
The program below, RndAcc.bas, is an example that calculates the size of the record. RndAcc.bas opens the RndAcc.txt text file in BINARY mode and reads random access records from the file.
Snip and save the following block of text as RndAcc.txt
0000000000:14159265358979323846264338327950288419716939937510 0000000001:58209749445923078164062862089986280348253421170679 0000000002:82148086513282306647093844609550582231725359408128 0000000003:48111745028410270193852110555964462294895493038196 0000000004:44288109756659334461284756482337867831652712019091 0000000005:45648566923460348610454326648213393607260249141273 0000000006:72458700660631558817488152092096282925409171536436 0000000007:78925903600113305305488204665213841469519415116094 0000000008:33057270365759591953092186117381932611793105118548 0000000009:07446237996274956735188575272489122793818301194912 0000000010:98336733624406566430860213949463952247371907021798 0000000011:60943702770539217176293176752384674818467669405132 0000000012:00056812714526356082778577134275778960917363717872 0000000013:14684409012249534301465495853710507922796892589235 0000000014:42019956112129021960864034418159813629774771309960 0000000015:51870721134999999837297804995105973173281609631859 0000000016:50244594553469083026425223082533446850352619311881 0000000017:71010003137838752886587533208381420617177669147303 0000000018:59825349042875546873115956286388235378759375195778 0000000019:18577805321712268066130019278766111959092164201989
'RndAcc.bas Random file access of a ASCII text file CLS DIM a$, x%, x1$, lenf%, i%, numrecs%, field% PRINT "RndAcc.txt is fixed record length including the trailing crlf." OPEN "RndAcc.txt" FOR INPUT AS FP1 LINE INPUT FP1, a$ CLOSE FP1 field% = LEN(a$) + 2 lenf% = LOF("RndAcc.txt") OPEN "RndAcc.txt" FOR INPUT AS FP1 PRINT " First few lines in the file." FOR i% = 0 TO 5 LINE INPUT FP1, a$ PRINT a$ NEXT CLOSE FP1 OPEN "RndAcc.txt" FOR BINARY AS FP1 RECLEN field% numrecs% = lenf% / field% PRINT "field = "; field%; " numrecs = "; numrecs%; " Last record = "; numrecs% - 1 DO INPUT "Input record number to read ", x1$ IF x1$ = "" THEN PRINT "Exiting now !" EXIT LOOP END IF x% = VAL(x1$) RECORD FP1, x GET$ FP1, a$, field% PRINT a$ LOOP CLOSE FP1
RndAcc.txt is fixed record length including the trailing crlf. First few lines in the file. 0000000000:14159265358979323846264338327950288419716939937510 0000000001:58209749445923078164062862089986280348253421170679 0000000002:82148086513282306647093844609550582231725359408128 0000000003:48111745028410270193852110555964462294895493038196 0000000004:44288109756659334461284756482337867831652712019091 0000000005:45648566923460348610454326648213393607260249141273 field = 64 numrecs = 19 Last record = 18 Input record number to read 8 0000000007:78925903600113305305488204665213841469519415116094 Input record number to read 12 0000000011:60943702770539217176293176752384674818467669405132 Input record number to read Exiting now !
RECORD is used to move a pointer, within the file, to a specific record.
Syntax:RECORD hFile AS FILE, _ RecordNumber AS INTEGER _ [, LocationInRecord] Parameters: |
RECORD FP1, 5
would move the pointer to the fifth record in the file.
REC returns an integer containing the current record number.
Syntax:RetVal = REC(hFile AS FILE) Return Value:
Parameters:
|
LOC returns an integer containing the position of a pointer within the current record.
Syntax:RetVal = LOC(hFile AS FILE) Return Value:
Parameters:
|
👉 For LOC to work correctly the file must to be opened
OPEN "Data.bin" FOR BINARY AS FP1 RECLEN Datar RECORD FP1, 5 'move to the beginning of the 5th record x = LOC(FP1) 'x would be equal to 0 RECORD FP1, 5, 10 'move to the 10th character in the 5th record x = LOC(FP1) 'x would be equal to 10
RECCOUNT returns an integer containing the number of records in the random access file.
👉 After RECCOUNT has been called, the file pointer is left at the end of the file. The REC and LOC functions could be used to determine and save the current position of the file pointer before calling RECCOUNT and then, after RECCOUNT has been called, the saved REC and LOC values could be used as arguments in a RECORD function call to move the file pointer back to the original record and position.
Syntax:RetVal = RECCOUNT(hFile AS FILE) Return Value:
Parameters:
|
Writing and reading a Random Access file.
'Simple Random Access database DIM inpt$ DIM str1$ DIM FileName$ TYPE DATAREC FName [10] AS CHAR MName [10] AS CHAR LName [10] AS CHAR Age AS INTEGER END TYPE DIM Datar AS DATAREC INPUT "Filename of database to open ? ", FileName$ IF EXIST(FileName$) THEN OPEN FileName$ FOR BINARY AS FP1 RECLEN Datar ELSE INPUT "File does not exist. Create?(Y/N)", str1$ IF UCASE$(str1$) = "Y" THEN OPEN FileName$ FOR BINARY NEW AS FP1 RECLEN Datar ELSE CLOSE END END IF END IF jmp1: PRINT "Press 0 to quit" PRINT "Press 1 to add record" PRINT "Press 2 to get record" INPUT inpt$ IF inpt$ = "0" THEN GOTO finis END IF IF inpt$ <> "1" AND inpt$ <> "2" THEN GOTO jmp1 END IF IF inpt$ = "1" THEN CALL AddRecord() END IF IF inpt$ = "2" THEN CALL GetRecord() END IF GOTO jmp1 finis: CLOSE FP1 END SUB AddRecord () LOCAL AddRec$ LOCAL RecNum% DO RecNum% = RECCOUNT(FP1) PRINT "Database contains"; STR$(RecNum%); " records." INPUT "Add record number ", RecNum% RECORD FP1, RecNum INPUT "First Name ", Datar.FName$ INPUT "Middle Name ", Datar.MName$ INPUT "Last Name ", Datar.LName$ INPUT "Age ", Datar.Age% PUT$ FP1, &Datar, SIZEOF(Datar) INPUT "Add another record(Y/N)? ", AddRec$ RecNum% ++ LOOP UNTIL UCASE$(AddRec$) = "N" END SUB SUB GetRecord () LOCAL GetRec% LOCAL RecNum% DO INPUT "Get record number(0 to quit) ", GetRec% IF GetRec% = 0 THEN EXIT LOOP END IF RECORD FP1, GetRec GET$ FP1, &Datar, SIZEOF(Datar) PRINT Datar.FName$ PRINT Datar.MName$ PRINT Datar.LName$ PRINT Datar.Age% LOOP END SUB