File Operations |
Top Previous Next |
File operations allow you to read and write data to permanent storage devices such as a hard drive, floppy or removable media. They can also be used to send data to peripherals attached to your computer, such as a printer. Opening files for reading and writing The OPENFILE function initiates the connection between your program and the outside world. It has as syntax of: Error =OPENFILE (Variable, filename, flags ) The variable must be either of type FILE for an ASCII file or BFILE to open the file in binary (raw) mode. The flags parameter is a quoted string and can be one of "R" for reading, "W" for writing , "A" for appending to an existing file. For binary files the flags parameter can also be "R+" to open an existing file for both reading and writing. The function will return 0 if the file was successfully opened or 1 if the file could not be created or opened. If the function fails you should not attempt to read or write to the fiel. Appending opens the file, or creates it if it doesn't exist, and sets the file pointer to the end of the file (EOF). The W mode will create a new file, or empty an existing one, and set the file pointer to the beginning of the file. You are allowed to read from the file in both W and A modes. DEF myfile as BFILE Closing open files After you are finished reading or writing to a file you must close it to make sure that system resources are returned to Windows. If you leave too many files open at once you will receive an error message. Use the CLOSEFILE statement to close any open file. Example: OPENCONSOLE The previous example attempts to open a file for writing in the C:\ directory called "EBASICTEST.TXT". After opening the file, it writes one line of text to the file and then closes the file. Writing to the file In the example a new function was introduced, WRITE. WRITE returns 0 on success and can work with both binary and ASCII (text) files. WRITE expects two arguments, the variable initialized with OPENFILE and the data to be written. How the data is written depends on whether or not an ASCII (FILE) variable or binary (BFILE) variable was used to open the file. In a binary file all data is written in raw form and will occupy the full size of the dimensioned variable. For example a standard STRING is 255 bytes: DEF myfile as BFILE The length of the file will be 255 bytes in this case. However using an ASCII file the WRITE statement will only write the contents of the string and automatically terminate the string with a linefeed/carriage return pair. DEF myfile as FILE The length of the file would be 7 bytes in this case and be loadable in any text editor. Numeric data is also treated differently in ASCII and binary files. In binary mode numeric data is written in its raw form which occupies the same amount of bytes it would in memory. For example an INT variable is 4 bytes in memory and will be 4 bytes in a disk file written in binary mode. For an ASCII file the size depends on the number of decimal places specified by the SETPRECISION command DEF myfile as BFILE Would write 4 bytes to the file. DEF myfile as FILE The number of bytes written depends on the setting of SETPRECISION. The default is two decimal places. A space character is always written in ASCII mode following a numeric type to separate data and to allow reading a continuous stream of numbers using the READ function. STRING types are always followed by a carriage return/line feed pair in ASCII mode. To combine separate strings on one line use concatenation or the APPEND$ function. See Also: The Variables section for information on raw data sizes for all of the data types supported by EBASIC. Reading from the file Writing to files would not be of much use if we could not read what we wrote. The READ function returns 0 on success and has the syntax of: Error = READ ( file, variable ) file must be a variable of type FILE or type BFILE and have been successfully initialized with the OPENFILE function. variable can be any built in type for ASCII files. Binary files also allow direct writing of UDTs. OPENCONSOLE When working with ASCII files the trailing carriage return/line feed character is not returned. Numeric data separated by any non numeric character can be read by continually calling the READ function and watching for the end of file with the EOF function. DEF myfile as FILE When working with binary files it is important to remember that READ will attempt to read as many bytes as required to fill in the variable. For numeric types this is dependant on the size of the type, an INT is 4 bytes for example. For STRING types READ will try and read the full dimension of the string, 255 bytes for normal strings. Arrays will be read/written to the full size of the array regardless of the index specified. Determining the length of files The LEN function works with file variables and returns the length of the open file in bytes. Length = LEN (myfile ) Moving the file pointer The SEEK command allows setting a binary file pointer to a position for reading or writing, it will not work with ASCII files. SEEK also allows obtaining the current file position. SEEK filevariable, position position = SEEK(filevariable) Position specified the zero-based byte offset to begin reading or writing data. The second form of seek returns the current position. Random Access Files The READ and WRITE functions are known as sequential file operations. They read and write one piece of data at a time until the end of file is reached. For small files this is fine and very manageable. Lets consider, however, a very large file like an address book. If you have 200 names and addresses stored in a file and want to read the 125th name you would need to read 124 entries before you get to the one you want. Luckily, there is a better way. The GET and PUT statements operate on a binary file using a record number as a parameter. Instead of having to access the 125th entry by reading the entire file you can get to that entry directly. The syntax of GET and PUT is: GET filevariable, record, variable PUT filevariable, record, variable File variable must be of type BFILE. The variable to be written can be a user type (UDT) allowing complex records to be used. The record number must be greater than zero. TYPE HighScoreTopTen
This would write the 7th record of the file with the contents of TopTen. The number of bytes written for each operation depends on the size of the UDT. You can determine the length of a UDT by using the LEN function with either the name of a defined UDT variable or the typename itself DEF TopTen as HighScoreTopTen Copying files Copies a file from a source directory to a destination. The syntax of COPYFILE is: error = COPYFILE(source, dest, fail) Source and destination are strings containing the full paths of the file to copy. If fail = 1 then the file will not be overwritten if it already exists in the destination directory. If fail = 0 then the file will be overwritten. COPYFILE returns 0 on error. Deleting files Deletes the specified file. The syntax of DELETEFILE is: error = DELETEFILE(name) Name is a string containing the full path to the file. DELETEFILE returns 0 if the file does not exist or is locked by another process. Creating Directories CREATEDIR is used to create a new directory under an existing one. error = CREATEDIR(name) Name is a string containing the full path to the directory. The name should not end with a '\\' character. CREATEDIR returns 0 on error and cannot create multiple levels of new directories. Each level must be created individually. IF CREATEDIR("c:\\My Programs") Removing directories REMOVEDIR is used to remove directories. The directory must be empty before it can be removed. The syntax of REMOVEDIR is: error = REMOVEDIR(name) Name is a string containing the full path to the directory. The name should not end with a '\\' character. REMOVE returns 0 on error. Reading directories FINDOPEN function To read all of the file names in a directory use the FINDOPEN function to get a handle to the directory first. Once a directory is opened the names of the files can be obtained with the FINDNEXT function. The syntax of FINDOPEN is: handle = FINDOPEN(directory) Directory is a string the contains the full path to the directory plus any wildcard symbols for file matching. Example: "c:\\windows\\*.txt". handle is an integer variable. FINDOPEN returns 0 if the directory could not be opened for reading. FINDNEXT function After a directory is successfully opened with the FINDOPEN function use FINDNEXT to retrieve the filenames in a loop. FINDNEXT returns an empty string when all of the file names have been retrieved, an optional attribute parameter returns the files attributes. The syntax of FINDNEXT is: name = FINDNEXT(handle {, attrib}) Handle is the integer value returned by FINDOPEN. For a list of possible returned attributes see FINDNEXT in the alphabetical reference. FINDCLOSE statement After you are finished reading a directory you must close the handle with FINDCLOSE. If the handle is not closed memory loss will occur. The syntax of FINDCLOSE is: FINDCLOSE handle You must not close a handle more than once. OPENCONSOLE Opening the system file dialog FILEREQUEST opens a standard file dialog and returns a string containing the fully qualified pathname to the file. Name$ = FILEREQUEST (prompt, parent, type {, filter} {,ext} {,flags} {,Initial Directory}) If type equals 1 then an ‘Open’ dialog is used. If type equals 0 then a ‘Save As’ dialog is opened. The optional filter variable limits the dialog to showing only certain file types. The string consists of ordered pairs separated by the '|' character and ending with two ||. Example: Filter$ = "Text files|*.txt|All Files|*.*||" A default extension can be supplied in the optional ext parameter and will be used if the user does not type in an extension. This is a string parameter and should not contain the '.' To allow users to select multiple files supply @MULTISELECT for the flags parameter. The returned string will contain complete paths to all of the files selected separated with the '|' character. If only one file is selected it will be terminated with the '|' character. The following example shows how to extract the filenames from the returned string: REM Define a buffer to hold the returned filenames. |