Syntax:result = LOC(#n) | result = SEEK(#n) Source: PowerBASIC built-in functions, implemented via SetFilePointer
Description
Both LOC and SEEK query the current file pointer position, but they return different values depending on the file mode:
LOC(#n) returns the logical position: current record number in RANDOM mode, or current byte position in BINARY mode.
SEEK(#n) returns the 1-based byte position regardless of mode, with BINARY files returning position and RANDOM files returning the position of the next record (1-based).
Internally, both functions call the Win32 SetFilePointer with a distance of 0 and FILE_CURRENT, which returns the current file pointer without moving it. The result is then adjusted based on the file mode (dividing by record length for LOC in RANDOM mode).
Parameters
Parameter
Description
n
The integer file number to query. The file must be open for BINARY or RANDOM access.
Return Values by File Mode
Function
BINARY Mode
RANDOM Mode
OUTPUT/APPEND
LOC(#n)
Current byte position (0-based, then +1?) Returns bytes read/written at current position
Current record number (1-based) LOC = (byte_pos / LEN) + 1
Number of bytes written since last OPEN
SEEK(#n)
1-based byte position of next GET/PUT SEEK = byte_pos + 1
1-based byte position SEEK = byte_pos + 1
Not applicable
Example
TYPE Employee
id AS LONG
nam AS STRING * 32
END TYPE
FUNCTION PBMAIN() AS LONG
LOCAL emp AS Employee
LOCAL pos AS LONG
OPEN "employees.dat" FOR RANDOM AS #1 LEN = 36
' Read through all records, tracking position
WHILE NOT EOF(1)
pos = LOC(1) ' current record number
GET #1, , emp
PRINT "Record "; pos; ": "; emp.id; " "; emp.nam
WEND
PRINT "Total records read: "; LOC(1) - 1
CLOSE #1
FUNCTION = 0
END FUNCTION
Binary Mode Position Tracking
OPEN "data.bin" FOR BINARY AS #2
GET #2, , val1
PRINT "LOC after read: "; LOC(2) ' bytes read so far (e.g. 4)
PRINT "SEEK position: "; SEEK(2) ' next byte position (e.g. 5)
GET #2, 10, val2 ' seek to position 10
PRINT "LOC after seek: "; LOC(2) ' 10
PRINT "SEEK position: "; SEEK(2) ' 14 (after reading 4 bytes)
CLOSE #2
Generated Assembly
LOC(#n) - Query Current Position via SetFilePointer
; LOC(#n) implementation using SetFilePointer with FILE_CURRENT (no move)
mov rcx, [rbp - handle_offset] ; hFile = stored file handle
xor rdx, rdx ; lDistanceToMove = 0 (no movement)
xor r8, r8 ; lpDistanceToMoveHigh = NULL
mov r9, 1 ; dwMoveMethod = FILE_CURRENT (1)
call [__imp_SetFilePointer] ; returns current position in EAX
; In RANDOM mode: divide by record length to get record number
; record_num = (current_pos / record_len) + 1
; In BINARY mode: return the byte position directly
; (some implementations add 1 for 1-based or keep 0-based)
; For RANDOM mode adjustment:
xor rdx, rdx ; clear high for division
mov rcx, <record_length> ; divisor = LEN from OPEN
div rcx ; RAX = position / record_length
inc rax ; 0-based -> 1-based record number
mov [rbp - loc_result], rax ; store LOC() result
SEEK(#n) - Query as Function (vs Statement)
; SEEK(#n) function implementation
mov rcx, [rbp - handle_offset] ; hFile = stored file handle
xor rdx, rdx ; lDistanceToMove = 0
xor r8, r8 ; lpDistanceToMoveHigh = NULL
mov r9, 1 ; dwMoveMethod = FILE_CURRENT
call [__imp_SetFilePointer] ; returns current byte position in EAX
; Convert 0-based byte position to 1-based
inc rax ; SEEK = current_pos + 1
mov [rbp - seek_result], rax ; store SEEK() result
LOC vs SEEK Comparison
Aspect
LOC(#n)
SEEK Statement
SEEK(#n) Function
Type
Function (returns value)
Statement (no return)
Function (returns value)
Read/Write
Read current position
Set new position
Read current position
RANDOM mode
Record number (1-based)
Set record number (1-based)
Byte position (1-based)
BINARY mode
Byte position
Set byte position (1-based)
Byte position (1-based)
Win32 API
SetFilePointer (query)
SetFilePointer (set)
SetFilePointer (query)
MoveMethod
FILE_CURRENT, dist=0
FILE_BEGIN
FILE_CURRENT, dist=0
Imported WinAPI Functions
Function
DLL
Purpose
SetFilePointer
kernel32.dll
Query current file pointer position (when called with distance=0 and FILE_CURRENT), or set position (when called with FILE_BEGIN)
Notes
LOC(#n) and SEEK(#n) are read-only queries—they do not move the file pointer.
SEEK #n, pos (statement form) does move the file pointer. See the SEEK Statement documentation for details.
In RANDOM mode, LOC(#n) returns the record number that was last read or written, not the next record. After GET #1, 5, rec, LOC(1) returns 5.
In OUTPUT/APPEND mode, LOC(#n) returns the number of bytes written since the file was opened.