NAME

open - open a file

SYNOPSIS

open FileSpec [for Mode] as [#]FileNum [len = Len]
open Mode2, [#]FileNum, FileSpec[, Len]

DESCRIPTION

The open statement initializes or "opens" I/O with a file given by the string expression FileSpec.  A mode identifies the method of access.  Len is a numeric expression the meaning of which is context dependent.  For convenience FileNum, a numeric expression, is associated with the open file and used to identify the open file in most subsequent I/O statements.  The association between the file number and the actual file exists until the file number is closed, either by an explicit call to close or one of the other BASIC statements that closes all open files as a side effect.  FileNum must be between one and a maximum value of 100. 

Except as a pipe specification (see below), FileSpec is taken as a UNIX filename which may specify either an ordinary disk file or a tty file.  A tty file is a special UNIX file which actually refers a communication channel for a terminal.  If FileSpec does not refer to a pre-existent tty, it taken as a disk file.  Thus if FileSpec does not refer to an existing file, implying the file needs to be created, it is created as a disk file. 

If FileSpec is of the form "PIPE: command", a pipe is established to the UNIX command given.  The command is executed as if it were typed at the terminal using the UNIX shell sh.  A pipe is a direct communication channel to a similar channel of another program.  From the point of view of the BASIC program, output to the pipe is sent directly to the standard input of the command and input from the pipe is received directly from the standard output of the command. 

In the first form of the open statement, Mode specifies the method of access and is among the following:

            Mode      Method of Access
 
inputsequential input only
outputsequential output only
appendsequential output only, appending
randomrandom access or sequential bidirectional I/O

If Mode is omitted, random is assumed. 

In the second form of the open statement, Mode2 specifies the method of access and is a string expression, the first character of which must match the first character of one of the Modes listed in the table above. 

Opening a file for input only forbids subsequent writing.  Opening a file for output only forbids subsequent reading.  No such restriction exists for bidirectional I/O.  If FileSpec refers to a file that does not exist, it is created unless the file is to be open for input only. 

Appending is the same as ordinary outputting for tty’s and pipes.  For disk files, appending means that subsequent writing will extend the file without disturbing the original initial portion.  Outputting without appending means that writing begins at the beginning of the file and the original portion of the file is lost.  A simpler view of appending may be to view not appending as the special case where the file is initially truncated to empty.  Thereafter, whether appending or not, writing will extend the file from its end. 

Opening a disk file for random indicates the special random access bidirectional mode.  In general, all input and output is performed sequentially and directly to a file.  Random I/O is the exception.  Random I/O introduces a (user accessible) buffer between the sequential I/O statements and the file.  The get and put statements are used to explicitly read and write the buffer to the file.  The buffer may be read or written to any location within the file at any time providing random access.  Within the buffer, I/O may be performed sequentially.  More commonly however, fields are set up within the buffer (see field) and these fields are manipulated as strings facilitated by the lset and rset statements.  The length of the buffer in bytes is given by Len.  Len is interpreted as an unsigned integer: a negative Len yields a buffer length of 65536 - Len.  If Len is omitted, 128 is assumed. 

If a tty is open for input, Len is the number of seconds to wait for input before giving up on a read attempt.  If Len is omitted, the program will wait forever if necessary. 

EXAMPLE

The open statement allocates memory for a buffer to be used for I/O to the file or device.  It also sets the access mode to be used with the buffer.  The following statements open files named "s1" through "s4" for sequential output. 
	a$ = "Basmark Corporation"
	? "Sequential Files -- Using Form 1:"
	?
	? "1. OPEN FileSpec [FOR Mode] AS FileNum "
	open "s1" for output as 1
	write #1, a$
	close #1
	? "2. OPEN FileSpec [FOR Mode] AS [#] FileNum "
	open "s2" for output as #1
	write #1, a$
	close #1
	? "Sequential Files -- Using Form 2:"
	?
	? "3. OPEN Mode2, FileNum, FileSpec "
	open "O", 1, "s3"
	write #1, a$
	close #1
	? "4. OPEN Mode2, [#]FileNum, FileSpec "
	open "O", #1, "s4"
	write #1, a$
	close #1
Any pre-existing data in the files will be destroyed (open with append to avoid data destruction):
	? "5. Define File and Open for Append"
	file$ = "s5"
	open file$ for append as 1
	write #1, a$
	close #1
The example above illustrates an indirect FileSpec.  The next example opens the file "s5" and positions the file pointers so that any output to the file is placed at the end of existing data in the file.  The following statements open files named "r6" through "r9" for random output. 
	a$ = "Basmark Corporation"
	? "Random Access Files -- Using Form 1:"
	?
	? "6. OPEN FileSpec AS FileNum [LEN = Recl]"
	open "r6" as 1 len = 120
	for i = 40 to 120 step 40
		field #1, i as n$
		lset n$ = a$
		put #1, i
	next i
	close #1
	? "7. OPEN FileSpec AS FileNum "
	open "r7" as 1
	field #1, 40 as n$
	rset n$ = a$
	put #1
	close #1
	? "Random Access Files -- Using Form 2:"
	?
	? "8. OPEN Mode2, FileNum, FileSpec [,Recl]"
	open "R", 1, "r8", 80
	field #1, 40 as n$
	rset n$ = a$
	put #1
	close #1
	? "9. OPEN Mode2, [#]FileNum, FileSpec [,Recl]"
	open "R", #1, "r9", 80
	field #1, 40 as n$
	lset n$ = a$
	put #1
	close #1
The following example illustrates the use of pipes both for input and output.  The purpose of this program is to request the name of a user on the system, determine if the user is logged in and sent the user a greeting. 
	 10 on error goto 500
	 20 input "Who are you looking for"; user$
	 30 open "PIPE: who | grep "+user$ for input as #1
	 40 line input #1, who$
	 50 close #1
	 60 print who$
	 70 open "PIPE: write "+user$ for output as #1
	 80 print #1, "Tally-ho!"
	 90 print #1, "Greetings and Felicitations!"
	100 close #1
	110 end
	500 if erl <> 40 then on error goto 0
	510 print "Sorry, " user$ " isn't logged in."
	520 close #1
	530 resume 110
When executed, the output might look like this:
	Who are you looking for? ljl
	ljl        console      Aug 18 17:40
The name of the user is requested and the name is stored in user$.  Next, on line 30, a "file" is open for input which is the output piped from a command, in this case, "who | grep ljl." The output of the UNIX program "who" is piped to the UNIX pattern matching program "grep," in this case, the pattern is "ljl" and the matching line appears on standard output which is piped to the BASIC program as file number one.  On line 40, the line is read in.  If the user had not been logged in, no line would be available and a error condition would cause the error handling routine at line 500 to be executed.  The error routine would report the anomaly and exit gracefully.  Normally, however, the login entry is printed and the pipe is closed.  Then, on line 70, another pipe is opened, this time for output.  The command in this case is "write ljl" with its standard input attached to file number one.  The greeting is written to this file number and thus piped to the UNIX program "write" which prints it on the user’s terminal. 

The final example demonstrates opening another terminal (other than the terminal on which the program is invoked):

	open "/dev/tty11" as #1
	print #1, "Welcome to the Game of Stellar"
	input #1, "How many stars do you want"; a
	print #1, string$(a, "*")
	close #1
"/dev/tty11" refers to a terminal that is not set up for logging in.  Permission to read and write the terminal is also necessary.  If the user responds with "10", the output on "/dev/tty11" would be:
	Welcome to the Game of Stellar
	How many stars do you want? 10
	**********

SEE ALSO

close, field, get, lset, put, rset

DIAGNOSTICS

If FileNum is less than 1 or greater than the maximum number, a "Bad file number" error occurs. 

If Mode2 does not begin with an appropriate character, a "Bad file mode" error occurs. 

If an attempt is made to open a nonexistent file for input, a "File not found" error occurs. 

If FileNum is already open, a "File already open" error occurs. 

USAGE NOTES

Internally all disk files and pipes have buffers.  The length of random I/O buffers is discussed above.  The length of other buffers is 512 bytes.  Tty’s have no buffers. 

A buffer used for random I/O is never deallocated even after the file has been closed in order to prevent fielded strings from being corrupted.  If the same FileNum is used for random I/O again and the old buffer is large enough, the buffer is reused.  Otherwise a new buffer is allocated and the old buffer is lost forever.  If memory space is a premium, opening the FileNum with the largest buffer first is efficient. 

Note that it is possible to have a single UNIX file open several times at once, using different file numbers and different modes.  Care should be taken when writing a given file specification using one file number and reading it using another. 

A limit exists for the maximum number of UNIX files that may be open at once by a single program.  In practice, this limit is large (about 15). 

There is very little to recommend bidirectional pipes.  The possibilities for deadlock are legion.  If at all possible, it is probably wisest to open the pipe for output only and send the process’s output to a temporary file; then open the file for input and read it in. 

Basmark QuickBASIC adopts UNIX file naming conventions. 

from The Basmark QuickBASIC Programmer’s Manual by Lawrence Leinweber