| lock, unlock |
| open, close, freefile, |
| kill, name, setEOF |
| write#, print#, flush |
| input#, line input# |
| get, get$, put, put$, |
| eof, lof, fileattr, filescan |
| getattr, setattr |
| pathname$, pathscan$, filecopy |
| data, read$, datacount |
File Basics
In order to read or write information from/to a file, the file
must first be opened, using the Open command. There are five modes
in which a file may be opened - input, output, append, random and
binary. The input, output and append modes are called
sequential mode because a read/write can only take place right after the
last read/write. For random/binary modes, file read/write operations
can take place at any location within the file.
Here's an example of opening a file in each of the five modes.
open "myfile.txt" for input as #1 ' read only open "myfile.txt" for output as #1 ' write only, erases content open "myfile.txt" for append as #1 ' write only, at end of file open "myfile.txt" for random as #1 len=80 ' fixed length lines open "myfile.txt" for binary as #1 ' byte-level read/write
File Content
Files generally come in two flavors - binary and text files, with
a couple of variations of text files.
Binary data is simply non-text code, where the bytes of data do not interpret into the familiar ASCII text characters. Numeric values, machine language, and individual bit flags are some of the types of content that make up binary data - all of unreadable by human eyes.
PowerBASIC file statements and functions specifically work with these three kinds of file content. Opening, reading, writing, and closing are the basic capabilities - with a few dozen supporting features to make the task as easy as possible.
File Modes
To read from or write to a file it must first be "opened", which
simply means that a file's read/write options are defined and the
application locks the file for its (usually) exclusive use. When
the file is closed it is unlocked and available for other applications
to use.
In PowerBASIC there are five modes in which a file may be opened. They affect how the file may be read or edited.
Because all lines are of equal length and the start/end of each line is know, it is possible to randomly read or write any record.
In particular, numeric data is written in the same format as it is stored in memory - without converting it to a string series of ASCII characters. The numbers may be any of the data types supported by PowerBASIC, integer, floating-point numbers, etc., each of which are represented by a unique format and number of bytes in memory.
Bytes can be randomly read or written.
Closing a File
When a program complete all read/write operations on a file, it
closes the file, which releases it for use by other applications.
When a PowerBASIC program ends, PowerBASIC automatically closes all
files. However a file can also be explicitly closed within the program.
Files can even be opened/closed in different modes as many times as
needed during the execution of a program.
Reading From Files
In PowerBASIC there are three basic statements which read from a file. These
differ primarily in how much data is read - a variable, a list of variables,
a specific number of bytes, or entire lines and records.
Writing to a File
There are three functions which provide the ability to write to files.
These differ primarily on how the data is written - as text or binary
data.
Complementary Read/Write Statements
The read/write statements above can be grouped into the following
complementary pairs - where a read statement can access information
placed in the file by a write statement.
These are discussed in more detail below, but this overview helps understand where the statements are useful.
Line Input#, Print#
These two functions are complementary sequential file functions.
Line Input# reads an entire line and places it into a variable.
The Print# statements writes one or more variables to a file
in text format.
The programmer must manage the inclusion of CRLF characters to start/end lines of data.
These may be the most used file read/write functions. Text files are very popular with programmers because the content can be edited by simple text editors. This provides a level of security against file corruption.
Get/Put
For working with random access and binary files, PowerBASIC provides
the Get/Put statements.
Get reads a record from a random access file. It reads a variable or array from a binary file.
Put writes a record to a random access file. It writes a variable(s) or array(s) to a binary file
Read/write actions take place at the current pointer position, which can be changed using SEEK. File size may grow if the pointer position if set beyond the EOF.
Get/Put can work with standard text files, but their strength is in dealing with random access and binary files.
These are also very popular, particularly because of the ease with which large amounts of data can be written with minimal code.
Input#, Write#
These two functions are also complementary sequential file functions.
Write# puts data in a file that Input# can read. The format is
the industry standard comma separated values (CSV).
Write# puts data in a file, enclosed by quotes (strings) and separated by commas. Each Write# statement also writes a CR/LF at the end of the data.
Write#1, "he", "be" '"he","be" on a line by itself Input#1, a$, b$ ' reads "he" and "be"
These statements are not as popular, but since the CSV output is an industry standard and the data files can be read by other programs (such as Microsoft Excel), it continues to have loyal followers.
Get$/Put$
Essentially simpler versions of Get/Put, the Get$/Put$ statements
are an easier way to deal with data at the byte level. These are
limited to working with files opened in binary mode only.
Get$ reads a specific number of bytes (characters) and Put$ writes a specific number of bytes (characters).
Get$ #1, n&, s$ 'get n& bytes and put in variable s$ Put$ #1, s$ 'put s$ (however many bytes there are)
Read/write actions take place at the current pointer position, which can be changed using SEEK. File size may grow if variable size causes Put$ to write beyond EOF.
The popularity of these statements is similar to that of the Get/Put statements. Programmers readily switch between the simpler Get$/Put$ and more powerful Get/Put statements.
Special Array Support
Programmers like to work with arrays, particularly when dealing with
files, because of the convenience in writing many elements with a
single statement. The following PowerBASIC statements provide special
syntax to deal with handling arrays.
Here is a one-line description of the file functions which support reading/writing/creating arrays. More information on each is provided in the reference listing at the bottom of this page.
When dealing with sequential files, a text file can be read into an array, with one line of text per array element. Or, a string array can be written to a file with one array element per line.
When dealing with binary files, an array variable can be read or written with a single line of code.
These statements perform other read/write operations as well, but this section focused on just the array handling features.
File Position
PowerBASIC can track, or set, the current position in a file, which is where
the next read or write will take place. The two functions that provide file
positional information are:
PowerBASIC discourages the use of Loc in favor of the newer Seek function.
DATA Statements
PowerBASIC provides the DATA statement, which allows values to be stored
as part of a program's source code. When the program is executed the values
can be read into string variables with the READ$ statement.
In the following example, five DATA statements, each with five values, are shown along with the code to read all 25 values.
DATA 1,1,4,1,1 For y% = 1 to 5 DATA 1,1,4,1,1 For x% = 1 to 5 DATA 4,4,4,4,4 incr n% : z$ = READ$(n%) DATA 1,1,4,1,1 next x% DATA 1,1,4,1,1 next y%
This example might represent a 5x5 matrix of color values for creating a sprite. So while all 25 values could be stored in a single DATA statement, the five DATA statements actually provide a visual preview of the sprite shape.
The READ$ function gets a single value from the first DATA statement and places the value into a variable, starting with the first DATA statement in the program. Each successive READ$ gets the next DATA value, skipping to the next DATA statement once all values in the current DATA statement are read.
Each procedure in a PowerBASIC program can have its own set of DATA statements, with up to 64KB and 16,384 values.
File Functions Listing
Here's a simple listing of the file functions above, with a one-line
description of what the function does. Syntax and examples are given
in the next section.
File Functions Reference
Here are examples for each of the file functions. The
functions are listed in alphabetical order.
close #1 ' closes a single file close #2, #3 ' closes two open files close ' closes all open filesThe # symbol is optional. Buffers are flushed. Works with files and devices.
data "ab", "rs" ' strings, no quotes data 1, 4, 5, 7 ' numbers, but read as strings data "a b", " rs" ' strings
Each procedure has its own DATA statements. Quotes only needed if leading/trailing spaces are to be included in the values.
n% = DATACOUNT
Use to set the bounds of a For/Next loop to read all values.
result% = eof(1) ' -1 end of file, 0 not end of file result% = eof(#1) ' # is optional if eof(1) then 'eof has been reached end if
Must use valid file number. Works on binary file only if last operation was unsuccessful read.
field #1, width% AS var$ ' string variables only field #1, 30 as a$, 50 as b$ ' multiple variables supported
result& = fileattr(#1,1) ' file mode result& = fileattr(#1,0) ' open status Return Options: -3 device type (1-file, 2-device) -2 logical first byte (base) position of file -1 minimum read data Random-->record length, Input-->LEN value, Binary/Output/Append-->1) 0 open state. -1 true, 0 false 1 file mode 1-input, 2-output, 4-random, 8-append, 16-comm, 32-binary, 64-TCP, 128-UDP combinations allowed - Append = 8+2 = 10 2 file handle. can use with PowerBASIC OPEN HANDLE statement 3 enumerates existing file numbers. 1st # - FILEATTR(1,3) 2nd # - FILEATTR(2,3), etc. -1 if no more file numbers.
FILECOPY "c:\data\test.txt", "c:\data\text.bak" ' from,to
Both arguments include a file name. Neither can contain just a path. Wildcards cannot be used. The destination file will be overwritten, unless it is read-only or locked (causes run-time error).
f$ = filename$(#1) ' returns name of open file #1
Not valid with OPEN HANDLE, COMM/TCP/UDP OPEN.
filescan #1, RECORDS TO linecount&, WIDTH to maxwidth&
INPUT/BINARY mode only.
Input mode - assumes CR/LF line delimiter. Stops at Chr$(26) or end of file. Last line counted even if doesn't end in CR/LF.
flush #1, #2 'write buffers to disk, # is optional flush 'flush all files
open "myfile.txt" for output as freefile ' use directly result% = freefile ' get next valid file number
freefile is used to ensure that a program does not try to open a file with an already used number, which would cause a program error.
returns new number with each invocation, regardless if last number from last call was used to open a file.
get #1, recordnumber&, variable ' random-access mode get #1, bytelocation&, variable ' binary mode get #1, 25, var$ 'gets 25th record get #1,5,rec$ 'random access file - record 5 get #1,4,n% 'binary file - variable starting at byte 4 - bytes read = length of variable get #1,87,myarray$ 'binary file - array starting at byte 87 get$ #1,42 'binary file - read 42 strings, starting at pos
result& = GETATTR("c:\data\test.txt") result& = GETATTR("c:\data\")result& is OR'd combination of the following Attribute Codes:
0 or 128 Normal %NORMAL 1 Read-only %READONLY 2 Hidden %HIDDEN 4 System %SYSTEM 8 Volume Label %VLABEL 16 Directory %SUBDIR 32 Archived %ARCHIVEUse AND to test for specific attribute.
If (result& AND 1&) = 1 Then ... READONLY attribute set If (result& AND 2&) = 2 Then ... HIDDEN attribute set If (result& AND 4&) = 4 Then ... SYSTEM attribute set If (result& AND 8&) = 8 Then ... VLABEL attribute set If (result& AND 16&) = 16 Then ... SUBDIR attribute set If (result& AND 32&) = 32 Then ... ARCHIVE attribute setFile must exist! Does not work on "c:\" (root directory). Full pathname not required.
input #1, a%, b% ' input list of variables from
Data in file must be comma separated, with CR at end of line (Write# creates this format).
result$ = ISFILE ("c:\data\test.txt") ' -1 found, 0 not found
All attributes accepted (hidden, system, read-only, ...)
kill "c:\temp\test.bat" ' deletes test.bat kill "test.bat" ' deletes test.bat in current directory kill "*.bas" ' wildcards allowed
Fill must exist! Can include wildcard. Path can be included. Does not use Windows trashcan. Request to kill HIDDEN/SYSTEM files is ignored. Does not work on folders.
line input ; "prompt" ; var$ ' input from keyboard line input #1, var$ ' input from open file
Note: line input# expects lines to be separated by the line feed/carriage return character pair. If no such pair exists, the entire file will be read into the variable (up to the PowerBASIC 32K string length limit).
result&& = loc(#1)
Use of SEEK is recommended over LOC
result&& = LOF(1) ' bytes result&& = LOF(#1) ' # is optional
lock #1 ' locks entire file (INPUT, OUTPUT, APPEND) open "myfile.txt" for random as #1 lock #1, 25 ' locks only record 25 lock #1, 25 TO 40 ' locks records 25-40 open "myfile.txt" for binary as #1 lock #1, 25 ' locks 25th byte lock #1, 25 TO 40 ' locks bytes 25-40
Binary - byte level locking. BASE clause in OPEN statement determines how byte entries are applied.
Random - record level locking.
Sequential files -locking of entire file.
Locked file must be Unlocked before the file can be closed.
open "myfile.txt" for input result = lof(1)
name "myfile.txt" As "newfile.txt" ' renames a file name "c:\test.bat" As "c:\temp\temp.bat" ' rename/move file
File must exist! File cannot be opened or locked. Full path allowed. If target file exists, error occurs. Wild cards not permitted.
Can use to move file to new directory (cannot move directories).
open file$ for mode$ ACCESS LOCK as #1 len=reclen% ' syntax ' file$ can be filename or device ' modes: append, binary, input, output, or random ' lock types: shared, lock read, lock write, lock read write ' default record length for random-access files is 128 bytes ' default record length for sequential files is 512 bytes open "myfile" for input as #1 open "myfile" for output as #1 open "myfile" for append as #1 open "myfile" for binary as #1 open "myfile" for random as #1 len=80
Must use unique file number.
INPUT file must exist! If not exist, all other modes will create the file.
Access (this process): Read, Write, ReadWrite
Lock (other processes): LockShared, LockWrite, LockRead, LockReadWrite
LEN for random access (default 128). Also to define sequential access buffer.
BASE for random access only (sets first byes as 0 or 1)
f$ = "c:\data\text.txt" ' does not have to exist result$ = PATHNAME$(FULL, f$) ' c:\data\text.txt result$ = PATHNAME$(PATH, f$) ' c:\data\ result$ = PATHNAME$(NAME, f$) ' text result$ = PATHNAME$(EXTN, f$) ' .txt (includes period) result$ = PATHNAME$(NAMEX, f$) ' text.txt
f$ = "text.txt" ' file to find. no wildcards! d$ = "c:\data" ' folder to search d$ = "c:\data;d:\info" ' PATHSCAN$(FULL, f$, d$) ' PATHSCAN$(PATH, f$, d$) ' PATHSCAN$(NAME, f$, d$) ' PATHSCAN$(EXTN, f$, d$) ' PATHSCAN$(NAMEX, f$, d$) ' Default search paths: application folder current folder Windows32 Windows16 Windows folders in PATH environment
Returns "" if file not found. Multiple paths, separated by semicolons, are allowed. Path is optional. If path not given, or is "", then default search paths are used. Multiple search paths are allowed, separated by semicolons.
print #1, varlist ; ' prints to a file print varlist ' prints to screen
Semicolon at end means print immediately after last value. A comma would mean print at end of print zone (14 char wide). No value means print on next cursor line.
put #1, recordnumber&, variable ' random-access mode put #1, bytelocation&, variable ' binary mode open "myfile.txt" for binary as #1 put #1, 25, var$ ' puts 25th byte open "myfile.txt" for random as #1 len=40 put #1, 25, var$ ' puts 25th record put$ #1, var$ ' puts var at current pos
data "one", "two", "three" ' data statement with values a$ = read$(1) ' reads 1st value a$ = read$(2) ' reads 2nd value
If index > DATACOUNT, read$ returns "" (no error). If values are enclosed in quotes, leading/trailing spaces are preserved. Can only read DATA statements within current procedure.
result&& = seek(#1) ' returns position in file #1, # is optional ' random access - next record to write ' all other modes - next byte to read/write seek(#1,124) ' set file position to 124, # is optional ' random access - next record to write ' all other modes - next byte to read/write
When using seek, the BASE setting, which specifies the position of the first byte/record as 0 or 1, must be taken into account.
SETATTR("c:\data\test.txt", %HIDDEN) SETATTR("c:\data\test.txt", %READONLY)Allow attributes are:
0 Normal %NORMAL 1 Read-only %READONLY 2 Hidden %HIDDEN 4 System %SYSTEM 32 Archived %ARCHIVEFile must exist! Does not work on "c:\" (root directory). Full pathname not required. With attribute 0 - file is not read-only, not hidden, not system and not archived.
seteof #1 ' #1 is an open file seteof 5 ' # is optional
Works on open file only. Truncates at current position. Can also set position explicitly with SEEK.
unlock #1 ' unlocks entire file open "myfile.txt" for random as #1 unlock #1, 25 ' unlocks only record 25 unlock #1, 25 TO 40 ' unlocks records 25-40 open "myfile.txt" for binary as #1 unlock #1, 25 ' unlocks 25th byte unlock #1, 25 TO 40 ' unlocks bytes 25-40
For binary/random files, restores access to range of records or bytes. BASE clause in OPEN statement determines how byte entries are applied.
For sequential files, affects the entire file (no by-record or by-byte control).
Locked file must be Unlocked before the file can be closed.
write #1, "hello" write #1, a$, b$, c$
Strings are written in parentheses and all variables are separated by commas. A CRLF is written after the last variable.
Ending the variable list with ; replaces the CRLF with a comma, which allows writing additional data to the same line of text.
If you have any suggestions or corrections, please let me know.