Previous: 13 Files and the Operating System
Up: 13 Files and the Operating System
Next: 13.2 Tell and Seek
Previous Page: 13 Files and the Operating System
Next Page: 13.2 Tell and Seek

13.1 Block Input/Output

The file I/O functions discussed so far perform reading and writing of different types of data using formatted ASCII information stored in files. Each I/O operation acts on a stream of character bytes, and the appropriate conversions from characters to an internal representation is performed by the library routines. While it is convenient to have data stored in files in an ASCII form (such data can be read or written by other programs and devices such as text editors, printers, etc.), it can be tedious and inefficient to perform all that data conversion from ASCII to internal binary, and back to ASCII); particularly for structure type data with many members of different types.

C provides additional file I/O library functions which allow direct input or output of the binary, internal representation of data to files. This form of I/O is called block I/O, because data is transferred in blocks directly from the file to storage locations in memory with no conversion. It should be noted that the files that store such data are binary files and cannot be read or written directly by other operating system programs such as text editors or printer software. Only a program which knows the organization of binary information within the files can access them correctly.

The library functions provided for this type of I/O are fwrite() and fread(). The function fwrite() writes (i.e. appends) a block of data of specified size to a file. Similarly, fread() reads a block of data of specified size into a memory location. The prototypes for these functions are defined in stdio.h and they may be described as:

The function prototypes use the data type, size_t, defined in stdio.h, which is of an unsigned type. (This is the type actually returned by the sizeof operator. As stated above, fread() returns the number of items read. When an end of file is encountered before no_items items are read, the return value will be less than the number requested; so this may be used to indicate end of file. Also note that the first parameter of the prototype for fwrite() uses a const qualifier. This ensures that no attempt is made to change the object pointed to by buffer within the function. Many prototypes use const qualifiers in the parameter declarations to prevent unplanned changes.

To see how to use these functions, let us use them to copy a file. The program logic is straight forward: open the input and output files, read each block of characters from the input file into a buffer, write each block to the output file. When a short size block is read, terminate the loop, write the short block, and close the files. The code is shown in Figure 13.1.

We have declared a buffer of type signed char so it can store any arbitrary bytes. We have also declared a pointer, ptr, with the qualifier const, since it is to remain unchanged, and initialized it to point to the buffer, buf. After the files are opened, the while loop reads a block of 100 items of char size from the input file, and writes the block to the output file. The loop is terminated when less than 100 items are read, indicating less than 100 items were remaining in the file to be read, so the end of file has been reached. The number of items read are assigned to n. At this point, the number of data bytes in the buffer is stored in n, so writing a block of 100 items would result in some garbage output. (The data from the previous block is still present in the rest of the buffer). Instead, the final block of n items is written.

This program simply copies blocks of 100 bytes at a time from the input file to the output file. These files can be any type of file, such as text files, program files, other ASCII files, even binary files, at least on Unix systems. However, on some non-Unix systems, the system routines may not be able to read or write arbitrary binary information unless the mode strings passed to fopen() explicitly indicates opening a file for binary I/O by appending the character 'b' to the string. Thus, the mode strings must be "rb" or "wb" instead of "r" or "w". A program using block I/O to copy binary files on an IBM PC using DOS operating system and a TURBO C compiler is shown in Figure 13.2. The program is the same as before except for the mode strings used in function calls to fopen().



Previous: 13 Files and the Operating System
Up: 13 Files and the Operating System
Next: 13.2 Tell and Seek
Previous Page: 13 Files and the Operating System
Next Page: 13.2 Tell and Seek

tep@wiliki.eng.hawaii.edu
Sat Sep 3 07:17:28 HST 1994