Open Command

Purpose

Enables input/output (I/O) to a file or a peripheral device.

Syntax

Open pathname [For mode] [Access access] [share] [Commit] [Based 0/1] As [#]filenumber [Len=reclength]

Description

You must open a file before any I/O operation can be performed on it. Open allocates a buffer for I/O to the file and determines the mode of access to use with the buffer.

If the file specified by pathname doesn't exist, it is created when a file is opened for Append, Binary, Output, or Random modes.

If the file is already opened by another process and the specified type of access is not allowed, the Open operation fails and an error occurs.

pathname Required. String expression that specifies a file name - may include directory or folder, and drive.
mode Optional. Keyword specifying the file mode:
    Append - Opens a file for sequential writing and sets the file pointer at the end of file.
    Binary - Opens a file for sequential reading and writing.
    Input - Opens file for sequential reading.
    Output - Opens a file for sequential writing.
    Update - Opens a file for sequential reading and writing. Better optimized for (Rel)Seek then Binary.
    Random - Opens a file for random reading and writing. See Field for more information.
If unspecified, the file is opened for Random access.
access Optional. Keyword specifying the operations permitted on the open file:
    Access Read - Read access only, even when a file is Lock Write.
    Access Write - Write access only, even when a file is Lock Read.
    Access Read Write - Read/Write access, but file is not accessible when it is locked.
Note: Access cannot be combined with For Input, For Output, and For Update. For these modes, Access is automatically Access Read, Access Write, Access Read Write, respectively
share Optional. Keyword specifying the operations restricted on the open file by other processes:
    Shared - Other programs have access.
    Lock Read - Other programs have no Read Access.
    Lock Write - Other programs have no Write Access.
    Lock Read Write - Other programs have no Read or Write Access. This is the default.
Commit Optional. Writes data to the file immediately without buffering by GFA-BASIC 32 or the system.
Based Optional. Based 1 is default. Determines the number of the first record ( 0 or 1) to be used by Record#, Get#, and Put#.
filenumber Required. A valid file number in the range 1 to 511, inclusive. Use the FreeFile function to obtain the next available file number.
Len Optional. Number less than or equal to 32,767 (bytes). For files opened for random access, this value is the record length. For sequential files, this value is the number of characters buffered. Len <= 1 disables GFA-BASIC 32 buffering, default is 2048 bytes. The Len clause is ignored if mode is Binary.

Example

Dim fileno% = FreeFile

Open "C:\TEST.DAT" for Output As # fileno%

' …

Close # fileno%

Open "C:\TEST.DAT" for Input As # fileno%

' …

Close # fileno%

' Open for reading only

Open "C:\TEST.DAT" for Binary Access Read As # 1

' -

Close # 1

' Tidy up

Kill "C:\TEST.DAT"

Accessing I/O from multiple sources or threads

While it is possible to share file access among different users or threads, this is not always desirable, especially when dealing with sequential read/write files; however, locking the file so that it can only be accessed individually can cause an error if another application or thread or user accidentally tries to access it at the same time. To get round this issue, use the simple code in the example below in every application and/or thread that is likely to access the file to create a gateway:

// THIS CODE IS JUST TO SIMULATE ANOTHER USER ACCESSING THE FILE AND THE SETTING UP A STATUS WINDOW

Ocx Timer tmr : tmr.Interval = 2000 : tmr.Enabled = True        // Set up a Timer to simulate the first user activity

OpenW 1                                                         // Open a window...

Ocx Label lbl = "", 10, 10, 200, 15                             // ...and add a status label

Open App.Path & "\temp.dat" for Output As # 1                   // Simulate the first user accessing the file

// THIS IS WHERE YOUR MAIN CODE BEGINS

Local fileerror As Boolean                                      /* Create a variable to determine if file error occured */ _

// - this is needed as you should not jump out of a Try/Catch structure

tryagain:

Try

Open App.Path & "\temp.dat" for Append As # 2                 // Simulate the second user accessing the file

fileerror = False                                             // If successful, set error flag to false

Catch                                                           // Otherwise on an error

If Not fileerror

lbl.Text = "Error - " & Err$ & " (" & Err.Number & " )"     // [Extra Code] Set Status to show error and code

EndIf

fileerror = True                                              // Set error flag to True

~DoEvents                                                     // Allow other events to be processed

EndCatch

If fileerror Then GoTo tryagain                                 // If error flag is True, loop back and try again

lbl.Text = "File access OK"                                     // [Extra Code] Set Status to OK

~DoEvents                                                       // [Extra Code] Update label text

//...Add Your code to append data here...//

Close # 2

// THE REST OF THIS CODE IS EXTRA CODE TO TIDY UP

Close # 1

Do : Sleep : Until Win_1 Is Nothing

 

Sub tmr_Timer

Close # 1                                                     // [Extra Code] Simulate the first user signing off

tmr.Enabled = False                                           // [Extra Code] Turn off the Timer object

EndSub

For more information troubleshooting I/O issues with threads, see here.

Console: CONIN$ and CONOUT$

There are two reserved pathnames for console input (the keyboard) and console output: "CONIN$" and "CONOUT$". Initially, standard input, output, and error are assigned to the console. It is possible to use the console regardless of any redirection to these standard devices; just open handles to "CONIN$" or "CONOUT$" using Open (CreateFile.) Console I/O can then easily be performed with Input # and Print #, letting GFA-BASIC 32 take responsibility for the correct input.

A process can have only one console at a time. GFA-BASIC 32 applications are GUI programs and are not initialized with a console like DOS-applications. If you need a console (to display status or debugging information), you must first create one. There are two simple parameterless functions for this purpose.

Declare Function AllocConsole Lib "kernel32" () As Int

Declare Function FreeConsole Lib "kernel32" () As Int

Before opening "CONIN$" or "CONOUT$" a console must be obtained:

Declare Function AllocConsole Lib "kernel32" () As Int

Declare Function FreeConsole Lib "kernel32" () As Int

Declare Function SetConsoleTitle Lib "kernel32" Alias "SetConsoleTitleA" (ByVal lpConsoleTitle As String) As Long

Declare Function WriteConsole Lib "kernel32" Alias "WriteConsoleA" (ByVal hConsoleOutput As Long, lpBuffer As Long, _

ByVal nNumberOfCharsToWrite As Long, lpNumberOfCharsWritten As Long, lpReserved As Long) As Long

Dim a$

If AllocConsole()

~SetConsoleTitle("Win32 Console API Demo")

Open "conout$" for Update As # 1, Len = 1

Open "conin$" for Input As # 2, Len = 1

Print # 1, "Test"

Print # 1, _File(# 1)

Print # 1, _File(# 2)

Input # 2, a$

WriteConsole(_File(# 1), V:a$, Len(a$), Null, Null)

Input # 2, a$

Close

~FreeConsole()

EndIf

The Len = 1 clause disables the internal buffering of GFA-BASIC 32.

The handle returned from _File(#) can be used in the console API functions taking a handle to the console like WriteConsole and ReadConsole.

Console: StdIn and StdOut

A console process uses handles to access the input and screen buffers of its console. A GUI process must create a console before it can use these standard handles (STDIN, STDOUT, and STDERR). Prevously, these handles had standard values 0, 1, and 2. In Win32 however, the (file) handles must be obtained using the GetStdHandle() API function. The return value is a file handle that can be used with API functions for I/O and for console read/write.

GFA-BASIC 32 supports the use of these standard handles without using API functions. Opening a file named "std:" will force GFA-BASIC 32 to use one of the standard handles. The For Output and For Input clause determine which standard handle is used.

Open "std:" for Input As # 1, Len = // STD_INPUT_HANDLE

Open "std:" for Output As # 2, Len = 1 // STD_OUTPUT_HANDLE

GFA-BASIC 32 redirects the standard devices to its own file handling mechanism. As a result, the normal BASIC I/O commands can be used to access the console.

Note: Regardless of any redirection to these standard devices, the console can still be used by opening handles to "CONIN$" or "CONOUT$".

Remarks

You can specify a hardware port in pathname$, although only supported by Windows 95/98/Me. Starting with NT, reading and writing ports using file handles is no longer allowed. The following names are defined:

LPT1:,...LPT4: parallel port (Centronics)
COM1:,...COM4: serial port (RS232)
CON: keyboard/screen

See Also

Close, _File(), Field, Record, RelSeek, Seek, Lof, Eof, Loc

{Created by Sjouke Hamstra; Last updated: 26/11/2023 by James Gaite}