home *** CD-ROM | disk | FTP | other *** search
/ Chip 1995 March / CHIP3.mdf / programm / prog3 / chap22.txt < prev    next >
Encoding:
Text File  |  1991-07-01  |  14.0 KB  |  351 lines

  1.  
  2.  
  3.  
  4.                                                        Chapter 22
  5.                                               BINARY INPUT/OUTPUT
  6.  
  7.  
  8. Any useful computer program must have a way to get data into it to
  9. operate on, and a way to get the results out to the user.  In part
  10. 1 of this tutorial, we studied how to get text in and out of the
  11. computer, now we will see how to get binary data in and out of the
  12. computer.  Most of the binary input and output will be to or from
  13. files because the data is always in a machine readable format, not
  14. one that a human reader can easily comprehend.  A block of binary
  15. data could be transmitted to a hardware device that is designed to
  16. respond to the data, or a block of data could be input from a
  17. hardware device reporting on some process.  A little more will be
  18. said about that later.
  19.  
  20.  
  21.  
  22. BINARY DATA OUTPUT
  23. _________________________________________________________________
  24.  
  25. Examine the program named BISEQOUT.ADA for an    ================
  26. example of outputting binary sequential data.      BISEQOUT.ADA
  27. Ada gives you three data input/output library    ================
  28. packages that are defined in the LRM, and
  29. required to be available with every Ada
  30. compiler.  They are listed by package name as follows;
  31.  
  32. Text_IO - This is used for text Input/Output and is always in a
  33.      sequential mode of operation.  Any file can be used for input
  34.      or output, but not both.  (This package has been in use during
  35.      most of this tutorial and was specifically described in
  36.      chapter 14.)
  37.  
  38. Sequential_IO - This is used for binary Input/Output and is always
  39.      in a sequential mode of operation.  Any file can be used for
  40.      input or output, but not both.
  41.  
  42. Direct_IO - This is used for binary Input/Output and can be used
  43.      in either a sequential or random mode of operation.  Any file
  44.      can be used for input, output, or input and output.
  45.  
  46. You should refer to either your compiler documentation or the LRM
  47. for the definition of these three packages.  All three are found
  48. in chapter 14 of the LRM.  Spend a little time studying the
  49. procedures and functions available with each to become familiar
  50. with the capability of each package.  The knowledge you have gained
  51. studying this tutorial to this point should enable you to
  52. understand most of the specifications of these three packages.
  53.  
  54.  
  55.  
  56.  
  57.  
  58.                                                         Page 22-1
  59.  
  60.                                  Chapter 22 - Binary Input/Output
  61.  
  62.  
  63. THE PACKAGE NAMED Low_Level_IO
  64. _________________________________________________________________
  65.  
  66. There is another input/output package that may be available with
  67. your compiler named Low_Level_IO.  This is not required by the LRM,
  68. but if it exists, it will be used for machine dependent
  69. input/output programming with your particular implementation.  If
  70. it exists with your compiler, the description of how to use it will
  71. be included with your documentation, and since it will be
  72. completely different with each compiler, no attempt will be made
  73. to explain its use here.
  74.  
  75.  
  76.  
  77. BACK TO BISEQOUT.ADA
  78. _________________________________________________________________
  79.  
  80. Although this program does very little, there are several steps
  81. that must be performed to output to a binary file.  They will be
  82. taken in order, so follow along closely.  First we must tell the
  83. system that we wish to use the external package Sequential_IO,
  84. which we do using a with clause in line 4.  Next we define a record
  85. type to illustrate one kind of data that can be output to the file,
  86. and declare a variable of the record type in line 18.
  87.  
  88. In order to use the sequential input/output package, we must
  89. instantiate a copy of it, because it is a generic package and
  90. cannot be used directly.  We do this in line 15, using the data
  91. type we wish to output to the file, then add the use clause in line
  92. 16 to make the new package readily available.  We need a file name
  93. to use as our internal file name, and we define it in line 19, but
  94. with a bit of difficulty because we have an overloaded file type
  95. available.  We have made Text_IO available to illustrate the
  96. problem, even though we don't use it in this program, and it
  97. contains a type named FILE_TYPE.  The package named Seq_IO that we
  98. have instantiated also contains a type named FILE_TYPE, the one we
  99. wish to use.  In order to tell the system which one we want, we
  100. must use the extended naming notation to differentiate between the
  101. two types.  This is done in line 19 of the example program.  With
  102. these steps, we are ready to begin the executable part of the
  103. program.
  104.  
  105. In a manner similar to that used for text files which we studied
  106. earlier, we create the file in line 23, in this case using the mode
  107. Out_File since we wish to write to the file.  As you recall, this
  108. also ties the internal name for the file to the external name we
  109. have chosen, NAMEFILE.TXT, which must follow the conventions for
  110. our particular Ada compiler and operating system.  If your
  111. operating system is substantially different, you may need to change
  112. this name.  We are finally ready to actually use the output file,
  113. so we load some nonsense data into the declared record variable in
  114. lines 25 and 26, then enter a loop where we will change the Age
  115. field of the record in order to have some varying data to write to
  116.  
  117.                                                         Page 22-2
  118.  
  119.                                  Chapter 22 - Binary Input/Output
  120.  
  121. the file.  This will make it more useful when we read the data from
  122. this file in another example program.
  123.  
  124.  
  125.  
  126. WRITING BINARY DATA TO THE FILE
  127. _________________________________________________________________
  128.  
  129. We actually write data to the file in line 30, where we use the
  130. procedure Write which is part of the instantiated package we named
  131. Seq_IO earlier, but since we have defined Seq_IO in a use clause,
  132. we do not need the qualifier "dotted" to the procedure name.  We
  133. mention the internal file name to tell the system which file we
  134. wish to write to, and the variable which we desire to output.  The
  135. variable to be output must be of the type for which the package was
  136. instantiated, resulting in a rule that all binary records output
  137. to any given file must be of the same type.  Even though they must
  138. be of the same type, they can be records of a variant record with
  139. different variants.
  140.  
  141. After writing 100 binary records, we close the file in the manner
  142. shown in line 33, and the program is complete.
  143.  
  144. We covered a lot of territory in the last few paragraphs, but it
  145. is useful information we will need in the next few example
  146. programs, and of course we will need it anytime we wish to actually
  147. use a binary file.  It should be clear that we could open several
  148. files, each storing a different data type, and write to them in any
  149. order provided that we wrote the proper data type to each file.
  150.  
  151. The resulting file, named NAMEFILE.TXT, will be used to illustrate
  152. binary reading in the next two programs, so it is imperative that
  153. you compile and execute this program.  After running it, you will
  154. find the file named NAMEFILE.TXT in the default directory of your
  155. system, and if you attempt to look at it with a text editor, it
  156. will have some very strange looking characters because it is a
  157. binary file.  You will notice however, that much of it will be
  158. readable because of the nature of the data selected for this file.
  159.  
  160.  
  161.  
  162. READING A BINARY FILE
  163. _________________________________________________________________
  164.  
  165. The example program named BISEQIN.ADA             ===============
  166. illustrates how to read from a binary file in a     BISEQIN.ADA
  167. sequential mode.  Everything in the declaration   ===============
  168. part of the program is identical to the last
  169. program except for the instantiation of an
  170. integer I/O package in line 15 for use later.
  171.  
  172. The only differences in the executable part is the use of the Open
  173. procedure from the Seq_IO package, which uses the In_File mode of
  174. file opening.  We can now read from the file we wrote in the last
  175.  
  176.                                                         Page 22-3
  177.  
  178.                                  Chapter 22 - Binary Input/Output
  179.  
  180. program, but we cannot write to it from this program.  We execute
  181. a loop 100 times where we read a record from the binary file each
  182. time through the loop, the record being identical to the record
  183. used to write the binary file.  If the record is different in
  184. structure or in data types, you may get anything upon reading, and
  185. it probably will not appear to have anything to do with the
  186. original data written, because the bytes will be mixed around.
  187.  
  188. All 100 elements are read in and those with the Age field greater
  189. than or equal to 82 are displayed to illustrate that the data
  190. really did get written.  Finally, the binary file is closed and the
  191. program terminated.
  192.  
  193.  
  194.  
  195. WHAT ABOUT PORTABILITY?
  196. _________________________________________________________________
  197.  
  198. Suppose you wrote the binary file with one Ada compiler, and
  199. attempted to read it using a different compiler.  It would be
  200. indeterminate whether or not it would work, because each
  201. implementor is free to define the internal bit patterns of the
  202. various types to fit his particular compiler.  Using such simple
  203. fields as those in this illustration would lead to a very good
  204. chance of portability, but using more elaborate records or arrays,
  205. would almost certainly cause incompatibility problems.  The
  206. solution to this problem is to read a file with the same compiler
  207. that was used to write it.  Of course a file written in a text
  208. format, using Text_IO, is portable and can be read with a different
  209. system.
  210.  
  211. Compile and execute this program and verify that the data really
  212. did get output as desired.  If you did not compile and execute the
  213. last example program, you did not generate the file named
  214. "NAMEFILE.TXT", and you cannot successfully execute this program.
  215.  
  216.  
  217.  
  218. RANDOM INPUT AND OUTPUT
  219. _________________________________________________________________
  220.  
  221. Examine the file named BIRANDIO.ADA for an       ================
  222. example of random input and output.  Random file   BIRANDIO.ADA
  223. access means that we can output data to the      ================
  224. file, or read data from the file just as if the
  225. file were an array.  The elements of the file do
  226. not have to be accessed in order.  We will illustrate all of this
  227. in this example program.
  228.  
  229. The declaration part of this program should look familiar to you
  230. since it is nearly identical to the last two example programs.  The
  231. biggest difference is the use of the Direct_IO package instead of
  232. the Sequential_IO package.  We instantiate a copy of this called
  233. Ran_IO, and use it to declare the internal filename,
  234.  
  235.                                                         Page 22-4
  236.  
  237.                                  Chapter 22 - Binary Input/Output
  238.  
  239. My_In_Out_File.  Next, as part of the declaration part of the
  240. program, we declare a function that will be used to output data in
  241. a neat form for us.
  242.  
  243.  
  244.  
  245. READING FROM THE RANDOM FILE
  246. _________________________________________________________________
  247.  
  248. Before we can do anything with the file, we must open it, and since
  249. we intend to read from and write to this file, we open it with the
  250. InOut_File mode.  Of course we use the internal filename we defined
  251. in line 21, and the external filename we have already written to.
  252. In line 38, we use the procedure Read, reading from the file we
  253. have opened, and we read the data into the record variable named
  254. Myself.  The thing that is really new here is the use of the number
  255. 37 as the third actual parameter of the procedure call.  This tells
  256. the system that we wish to read the 37th record from the designated
  257. file.  We use our Display_Record procedure to display the record
  258. read, then tell the system that we wish to read record number 25,
  259. and display it.  In line 42, we don't tell the system which record
  260. we want to read explicitly, so it returns the next record, the
  261. 26th, which we display.
  262.  
  263.  
  264.  
  265. WRITING TO THE RANDOM FILE
  266. _________________________________________________________________
  267.  
  268. We fill the three fields of the record variable with nonsense data
  269. in lines 46 through 48, and write the modified record to records
  270. 91, 96, and 97.  We write to record 97 because we don't specify a
  271. record and the system will default to the next successive record
  272. number.  In line 53 we call the procedure Set_Index with the value
  273. of 88 as the value to set, and as you may guess, it sets the record
  274. pointer to 88, which is the next record that will be read by
  275. default if no record number is stated.  The loop in lines 54
  276. through 57 read and display all records from 88 through the last,
  277. because we keep reading until we find an end of file.  You will see
  278. when you compile and execute this program that we did modify
  279. records numbered 91, 96, and 97.
  280.  
  281. You will find binary Input/Output to be very useful for temporary
  282. storage of large amounts of data, but you must keep in mind that
  283. any data you write using this technique may or may not be readable
  284. by some other system.  For this reason, binary output should not
  285. be used except for data that is meant to be read by another program
  286. compiled with the same Ada compiler as the data generator.  Be sure
  287. to compile and execute this program.
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.                                                         Page 22-5
  295.  
  296.                                  Chapter 22 - Binary Input/Output
  297.  
  298. PROGRAMMING EXERCISES
  299. _________________________________________________________________
  300.  
  301. 1.   Modify BISEQOUT.ADA to write the same data to two different
  302.      files, except when Age is between 50 and 60.  During this
  303.      range, one of the characters should be changed for one of the
  304.      files.
  305.  
  306. 2.   Modify BISEQIN.ADA to read both files output from exercise 1
  307.      and list the differences in the two files.
  308.  
  309. 3.   Combine BISEQOUT.ADA and BISEQIN.ADA in such a way that the
  310.      file is written in one loop, then read back in and displayed
  311.      in a successive loop.
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.  
  339.  
  340.  
  341.  
  342.  
  343.  
  344.  
  345.  
  346.  
  347.  
  348.  
  349.  
  350.  
  351.                                                         Page 22-6