home *** CD-ROM | disk | FTP | other *** search
-
-
-
- Chapter 22
- BINARY INPUT/OUTPUT
-
-
- Any useful computer program must have a way to get data into it to
- operate on, and a way to get the results out to the user. In part
- 1 of this tutorial, we studied how to get text in and out of the
- computer, now we will see how to get binary data in and out of the
- computer. Most of the binary input and output will be to or from
- files because the data is always in a machine readable format, not
- one that a human reader can easily comprehend. A block of binary
- data could be transmitted to a hardware device that is designed to
- respond to the data, or a block of data could be input from a
- hardware device reporting on some process. A little more will be
- said about that later.
-
-
-
- BINARY DATA OUTPUT
- _________________________________________________________________
-
- Examine the program named BISEQOUT.ADA for an ================
- example of outputting binary sequential data. BISEQOUT.ADA
- Ada gives you three data input/output library ================
- packages that are defined in the LRM, and
- required to be available with every Ada
- compiler. They are listed by package name as follows;
-
- Text_IO - This is used for text Input/Output and is always in a
- sequential mode of operation. Any file can be used for input
- or output, but not both. (This package has been in use during
- most of this tutorial and was specifically described in
- chapter 14.)
-
- Sequential_IO - This is used for binary Input/Output and is always
- in a sequential mode of operation. Any file can be used for
- input or output, but not both.
-
- Direct_IO - This is used for binary Input/Output and can be used
- in either a sequential or random mode of operation. Any file
- can be used for input, output, or input and output.
-
- You should refer to either your compiler documentation or the LRM
- for the definition of these three packages. All three are found
- in chapter 14 of the LRM. Spend a little time studying the
- procedures and functions available with each to become familiar
- with the capability of each package. The knowledge you have gained
- studying this tutorial to this point should enable you to
- understand most of the specifications of these three packages.
-
-
-
-
-
- Page 22-1
-
- Chapter 22 - Binary Input/Output
-
-
- THE PACKAGE NAMED Low_Level_IO
- _________________________________________________________________
-
- There is another input/output package that may be available with
- your compiler named Low_Level_IO. This is not required by the LRM,
- but if it exists, it will be used for machine dependent
- input/output programming with your particular implementation. If
- it exists with your compiler, the description of how to use it will
- be included with your documentation, and since it will be
- completely different with each compiler, no attempt will be made
- to explain its use here.
-
-
-
- BACK TO BISEQOUT.ADA
- _________________________________________________________________
-
- Although this program does very little, there are several steps
- that must be performed to output to a binary file. They will be
- taken in order, so follow along closely. First we must tell the
- system that we wish to use the external package Sequential_IO,
- which we do using a with clause in line 4. Next we define a record
- type to illustrate one kind of data that can be output to the file,
- and declare a variable of the record type in line 18.
-
- In order to use the sequential input/output package, we must
- instantiate a copy of it, because it is a generic package and
- cannot be used directly. We do this in line 15, using the data
- type we wish to output to the file, then add the use clause in line
- 16 to make the new package readily available. We need a file name
- to use as our internal file name, and we define it in line 19, but
- with a bit of difficulty because we have an overloaded file type
- available. We have made Text_IO available to illustrate the
- problem, even though we don't use it in this program, and it
- contains a type named FILE_TYPE. The package named Seq_IO that we
- have instantiated also contains a type named FILE_TYPE, the one we
- wish to use. In order to tell the system which one we want, we
- must use the extended naming notation to differentiate between the
- two types. This is done in line 19 of the example program. With
- these steps, we are ready to begin the executable part of the
- program.
-
- In a manner similar to that used for text files which we studied
- earlier, we create the file in line 23, in this case using the mode
- Out_File since we wish to write to the file. As you recall, this
- also ties the internal name for the file to the external name we
- have chosen, NAMEFILE.TXT, which must follow the conventions for
- our particular Ada compiler and operating system. If your
- operating system is substantially different, you may need to change
- this name. We are finally ready to actually use the output file,
- so we load some nonsense data into the declared record variable in
- lines 25 and 26, then enter a loop where we will change the Age
- field of the record in order to have some varying data to write to
-
- Page 22-2
-
- Chapter 22 - Binary Input/Output
-
- the file. This will make it more useful when we read the data from
- this file in another example program.
-
-
-
- WRITING BINARY DATA TO THE FILE
- _________________________________________________________________
-
- We actually write data to the file in line 30, where we use the
- procedure Write which is part of the instantiated package we named
- Seq_IO earlier, but since we have defined Seq_IO in a use clause,
- we do not need the qualifier "dotted" to the procedure name. We
- mention the internal file name to tell the system which file we
- wish to write to, and the variable which we desire to output. The
- variable to be output must be of the type for which the package was
- instantiated, resulting in a rule that all binary records output
- to any given file must be of the same type. Even though they must
- be of the same type, they can be records of a variant record with
- different variants.
-
- After writing 100 binary records, we close the file in the manner
- shown in line 33, and the program is complete.
-
- We covered a lot of territory in the last few paragraphs, but it
- is useful information we will need in the next few example
- programs, and of course we will need it anytime we wish to actually
- use a binary file. It should be clear that we could open several
- files, each storing a different data type, and write to them in any
- order provided that we wrote the proper data type to each file.
-
- The resulting file, named NAMEFILE.TXT, will be used to illustrate
- binary reading in the next two programs, so it is imperative that
- you compile and execute this program. After running it, you will
- find the file named NAMEFILE.TXT in the default directory of your
- system, and if you attempt to look at it with a text editor, it
- will have some very strange looking characters because it is a
- binary file. You will notice however, that much of it will be
- readable because of the nature of the data selected for this file.
-
-
-
- READING A BINARY FILE
- _________________________________________________________________
-
- The example program named BISEQIN.ADA ===============
- illustrates how to read from a binary file in a BISEQIN.ADA
- sequential mode. Everything in the declaration ===============
- part of the program is identical to the last
- program except for the instantiation of an
- integer I/O package in line 15 for use later.
-
- The only differences in the executable part is the use of the Open
- procedure from the Seq_IO package, which uses the In_File mode of
- file opening. We can now read from the file we wrote in the last
-
- Page 22-3
-
- Chapter 22 - Binary Input/Output
-
- program, but we cannot write to it from this program. We execute
- a loop 100 times where we read a record from the binary file each
- time through the loop, the record being identical to the record
- used to write the binary file. If the record is different in
- structure or in data types, you may get anything upon reading, and
- it probably will not appear to have anything to do with the
- original data written, because the bytes will be mixed around.
-
- All 100 elements are read in and those with the Age field greater
- than or equal to 82 are displayed to illustrate that the data
- really did get written. Finally, the binary file is closed and the
- program terminated.
-
-
-
- WHAT ABOUT PORTABILITY?
- _________________________________________________________________
-
- Suppose you wrote the binary file with one Ada compiler, and
- attempted to read it using a different compiler. It would be
- indeterminate whether or not it would work, because each
- implementor is free to define the internal bit patterns of the
- various types to fit his particular compiler. Using such simple
- fields as those in this illustration would lead to a very good
- chance of portability, but using more elaborate records or arrays,
- would almost certainly cause incompatibility problems. The
- solution to this problem is to read a file with the same compiler
- that was used to write it. Of course a file written in a text
- format, using Text_IO, is portable and can be read with a different
- system.
-
- Compile and execute this program and verify that the data really
- did get output as desired. If you did not compile and execute the
- last example program, you did not generate the file named
- "NAMEFILE.TXT", and you cannot successfully execute this program.
-
-
-
- RANDOM INPUT AND OUTPUT
- _________________________________________________________________
-
- Examine the file named BIRANDIO.ADA for an ================
- example of random input and output. Random file BIRANDIO.ADA
- access means that we can output data to the ================
- file, or read data from the file just as if the
- file were an array. The elements of the file do
- not have to be accessed in order. We will illustrate all of this
- in this example program.
-
- The declaration part of this program should look familiar to you
- since it is nearly identical to the last two example programs. The
- biggest difference is the use of the Direct_IO package instead of
- the Sequential_IO package. We instantiate a copy of this called
- Ran_IO, and use it to declare the internal filename,
-
- Page 22-4
-
- Chapter 22 - Binary Input/Output
-
- My_In_Out_File. Next, as part of the declaration part of the
- program, we declare a function that will be used to output data in
- a neat form for us.
-
-
-
- READING FROM THE RANDOM FILE
- _________________________________________________________________
-
- Before we can do anything with the file, we must open it, and since
- we intend to read from and write to this file, we open it with the
- InOut_File mode. Of course we use the internal filename we defined
- in line 21, and the external filename we have already written to.
- In line 38, we use the procedure Read, reading from the file we
- have opened, and we read the data into the record variable named
- Myself. The thing that is really new here is the use of the number
- 37 as the third actual parameter of the procedure call. This tells
- the system that we wish to read the 37th record from the designated
- file. We use our Display_Record procedure to display the record
- read, then tell the system that we wish to read record number 25,
- and display it. In line 42, we don't tell the system which record
- we want to read explicitly, so it returns the next record, the
- 26th, which we display.
-
-
-
- WRITING TO THE RANDOM FILE
- _________________________________________________________________
-
- We fill the three fields of the record variable with nonsense data
- in lines 46 through 48, and write the modified record to records
- 91, 96, and 97. We write to record 97 because we don't specify a
- record and the system will default to the next successive record
- number. In line 53 we call the procedure Set_Index with the value
- of 88 as the value to set, and as you may guess, it sets the record
- pointer to 88, which is the next record that will be read by
- default if no record number is stated. The loop in lines 54
- through 57 read and display all records from 88 through the last,
- because we keep reading until we find an end of file. You will see
- when you compile and execute this program that we did modify
- records numbered 91, 96, and 97.
-
- You will find binary Input/Output to be very useful for temporary
- storage of large amounts of data, but you must keep in mind that
- any data you write using this technique may or may not be readable
- by some other system. For this reason, binary output should not
- be used except for data that is meant to be read by another program
- compiled with the same Ada compiler as the data generator. Be sure
- to compile and execute this program.
-
-
-
-
-
-
- Page 22-5
-
- Chapter 22 - Binary Input/Output
-
- PROGRAMMING EXERCISES
- _________________________________________________________________
-
- 1. Modify BISEQOUT.ADA to write the same data to two different
- files, except when Age is between 50 and 60. During this
- range, one of the characters should be changed for one of the
- files.
-
- 2. Modify BISEQIN.ADA to read both files output from exercise 1
- and list the differences in the two files.
-
- 3. Combine BISEQOUT.ADA and BISEQIN.ADA in such a way that the
- file is written in one loop, then read back in and displayed
- in a successive loop.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 22-6