LOC / SEEK Functions
Syntax
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.