PowerBASIC file I/O uses numbered file handles (#n) and supports four access modes: sequential text (OUTPUT/APPEND/INPUT) and binary (BINARY). All operations ultimately map to the Windows API functions CreateFileA, ReadFile, WriteFile, SetFilePointer, and CloseHandle.
OPEN "filename" FOR OUTPUT|APPEND|INPUT|BINARY AS #npb_cg_emit_open (pb_codegen.c:6072)Opens a file and assigns it a file number #n. The mode determines the Win32 access flags and creation disposition.
| Parameter | Description |
|---|---|
filename | Path to the file (STRING literal or variable) |
mode | OUTPUT (write, create new), APPEND (write, keep existing), INPUT (read), BINARY (read+write) |
n | Integer file number (1-255) |
OPEN "data.txt" FOR OUTPUT AS #1 OPEN "log.txt" FOR APPEND AS #2 OPEN "input.txt" FOR INPUT AS #3 OPEN "data.bin" FOR BINARY AS #4
mov rcx, filename_ptr ; lpFileName mov rdx, <desired_access> ; see table below mov r8, 0 ; dwShareMode = 0 mov r9, 0 ; lpSecurity = NULL mov [rsp + 32], <creation> ; dwCreationDisposition mov [rsp + 40], 128 ; FILE_ATTRIBUTE_NORMAL mov [rsp + 48], 0 ; hTemplateFile = NULL call [__imp_CreateFileA] mov [rbp - handle_offset], rax ; save file handle ; FOR APPEND: seek to end additionally mov rcx, [rbp - handle_offset] xor rdx, rdx ; distance = 0 mov r8, 0 ; unused mov r9, 2 ; FILE_END call [__imp_SetFilePointer]
| Mode | dwDesiredAccess | dwCreationDisposition |
|---|---|---|
| INPUT | 0x80000000 (GENERIC_READ) | 3 (OPEN_EXISTING) |
| OUTPUT | 0x40000000 (GENERIC_WRITE) | 2 (CREATE_ALWAYS) |
| APPEND | 0x40000000 (GENERIC_WRITE) | 4 (OPEN_ALWAYS) |
| BINARY | 0xC0000000 (GENERIC_READ|WRITE) | 4 (OPEN_ALWAYS) |
PRINT #n, exprpb_cg_emit_writefile_handle (pb_codegen.c:5182)Writes formatted text to file #n using WriteFile with the stored file handle. The expression is formatted identically to console PRINT.
| Parameter | Description |
|---|---|
n | The file number to write to |
expr | Any printable expression (STRING, numeric, or comma/semicolon separated list) |
OPEN "output.txt" FOR OUTPUT AS #1 PRINT #1, "Hello World" PRINT #1, "Answer: "; 42 CLOSE #1
; Format expression (same as console PRINT) ; Then WriteFile using saved file handle: mov rcx, [rbp - handle_offset] ; file handle (NOT GetStdHandle) mov rdx, [rbp - print_ptr_offset] ; buffer mov r8, [rbp - print_len_offset] ; byte count lea r9, [rbp - written_offset] ; &bytesWritten mov [rsp + 32], 0 ; lpOverlapped = NULL call [__imp_WriteFile]
INPUT #n, variable$pb_cg_emit_read_file_line (pb_codegen.c:5291)Reads a line of text from file #n into a STRING variable. The file must be opened for INPUT or BINARY.
| Parameter | Description |
|---|---|
n | The file number to read from |
variable$ | A STRING variable to receive the line |
OPEN "input.txt" FOR INPUT AS #1 LOCAL line$ AS STRING INPUT #1, line$ PRINT line$ CLOSE #1
mov rcx, [rbp - handle_offset] ; file handle lea rdx, [rbp - buffer_offset] ; read buffer mov r8, <max_count> ; max bytes to read lea r9, [rbp - file_read_count] ; &bytesRead mov [rsp + 32], 0 call [__imp_ReadFile] ; NUL-terminate: mov r10, [rbp - file_read_count] ; bytes read lea r11, [rbp - buffer_offset] add r11, r10 mov byte [r11], 0 ; buffer[bytesRead] = 0
GET #n, [position,] variablepb_cg_emit_get (pb_codegen.c:780)Reads binary data from file #n into a variable. If position is specified, the file pointer is first set to that 1-based record position.
| Parameter | Description |
|---|---|
n | The file number (must be opened for BINARY) |
position | (Optional) 1-based record position |
variable | Variable to read into (size determines bytes read) |
LOCAL val AS LONG OPEN "data.bin" FOR BINARY AS #1 GET #1, 3, val ' read 4-byte LONG at record 3 CLOSE #1
; Optional SEEK for record position ; Get target address -> RDX mov rcx, [rbp - handle_offset] mov rdx, target_ptr ; buffer mov r8, <element_size> ; bytes to read lea r9, [rbp - file_read_count] mov [rsp + 32], 0 call [__imp_ReadFile]
PUT #n, [position,] variablepb_cg_emit_put (pb_codegen.c:880)Writes binary data from a variable to file #n. If position is specified, the file pointer is first set to that 1-based record position.
| Parameter | Description |
|---|---|
n | The file number (must be opened for BINARY) |
position | (Optional) 1-based record position |
variable | Variable whose data is written |
LOCAL val AS LONG val = 12345 OPEN "data.bin" FOR BINARY AS #1 PUT #1, 1, val ' write 4-byte LONG at record 1 CLOSE #1
mov rcx, [rbp - handle_offset] lea rdx, [rbp - buffer_offset] ; source data mov r8, <element_size> ; bytes to write lea r9, [rbp - written_offset] mov [rsp + 32], 0 call [__imp_WriteFile]
SEEK #n, positionpb_cg_emit_seek (pb_codegen.c:6132)Sets the file pointer to a specific 1-based record position for subsequent GET/PUT operations. Internally converts to a 0-based byte offset and calls SetFilePointer.
| Parameter | Description |
|---|---|
n | The file number |
position | 1-based record position (numeric expression) |
OPEN "data.bin" FOR BINARY AS #1 SEEK #1, 10 ' jump to record 10 GET #1, rec ' read record 10 CLOSE #1
; Convert 1-based position to 0-based cmp rax, 1 jge __pb_seek_positive xor rax, rax ; clamp to 0 jmp __pb_seek_ready __pb_seek_positive: sub rax, 1 ; 1-based -> 0-based __pb_seek_ready: mov rcx, [rbp - handle_offset] mov rdx, rax ; distance to move xor r8, r8 xor r9, r9 call [__imp_SetFilePointer]
CLOSE #npb_cg_emit_close (pb_codegen.c:6115)Closes the file associated with #n by calling CloseHandle and zeroing out the stored handle. Safe to call on an already-closed file (no-op).
| Parameter | Description |
|---|---|
n | The file number to close |
CLOSE #1 ' close file #1
mov rcx, [rbp - handle_offset] test rcx, rcx je __pb_close_skip ; already closed call [__imp_CloseHandle] mov qword [rbp - handle_offset], 0 ; zero out handle __pb_close_skip: