11 Files

Our objective in this section is to open a file and analyze the characters that it contains. This means that we will be doing input for the first time. At first, we will merely count the characters in the file but we will also use command-line arguments to apply the program to various files.

File handling in BETA is quite painless. Files for both input and output are implemented through a single pattern: file. This pattern is not in the standard environment betaenv but in an extended library called file which includes betaenv so it is sufficient to replace betaenv by file in the ORIGIN statement.

A complete program skeleton to read a file called data1 is as follows:

ORIGIN '~beta/basiclib/file'
--- program: descriptor ---
(# F: @File;
do 'data1' -> F.Name;
   F.openRead;

   (*... use F ...*)

   F.close;
#)

Here, F is declared as a file variable. The external file name is provided then openread is invoked. After use, the close operation should be called. Here we have used only three attributes of the pattern file:

Other useful attributes/operations are:

The standard while <not end-of-file> loop for sequentially handling the contents of a file translates into the following BETA code:

Loop: 
  (if not F.Eos then
      F.get -> ch;(* reading the next element *)
      ...
      restart Loop
  if);

Here is the whole program for counting the characters in the file data1. We have added visual feedback to the user by printing '.' on the screen for every 10 characters read. Note that using the input/output predicates directly (i.e. put or get) without . notation (i.e. f.get) accesses the standard streams (keyboard and screen).

Program 12: CountChar.bet

ORIGIN '~beta/basiclib/file'
---- program: descriptor ----

(# (* ----------------------------------------------
    *   count.bet: Simple file handling program
    *              -Counting characters-
    * ----------------------------------------------*)
   
   inFile: @file;
   Ch: @char;
   nc: @integer;
do
   'data1'->inFile.name ;  inFile.openRead;  (* OPENING *)
   'Reading: '->puttext;   inFile.name->putline;
   Loop: 
     (if not inFile.eos then
         inFile.get->Ch; 
         nc + 1->nc;
         (if nc mod 10 = 0 then '.'->put  if);
         restart Loop
     if);
   newline;
   nc->putint; ' characters in file'->putline;
   inFile.close;
#)

The output looks like this:

nil% CountChar
Reading: data1
....
41 characters in file

If the file data1 is not present, execution gives the following error message.

nil% CountChar

**** Exception processing
File exception for 'data1'
No such file

# Beta execution aborted: Stop is called
# Look at CountChar.dump'


Libraries Tutorial
© 1994-2004 Mjølner Informatics
[Modified: Thursday January 16th 2003 at 10:23]