An Introduction to Disk I/O

(BICS 265 Notes.13)

 

 

Learn the basics of using disk files in a C++ program...

 

 

 

Objects make it easier to write C++ programs.

You've been using two pre-defined objects to simplify console (screen and keyboard) I/O since the beginning of the course:

  • cout is an object of the ostream class. This class contains everything needed to send a stream of characters to a device (such as the display screen).

  • cin is an object of the istream class. This class contains everything needed to read a stream of characters from a device (such as the keyboard).

 

"These objects are created within standard header files and get included in your program via the iostream.h header file..."

 

Sending a stream of characters to disk is a more specific type of stream output. And reading a stream of characters from disk is a more specific type of stream input.

 

"If you're thinking in an object-oriented way, this should ring a bell..."

 

To simplify disk I/O, two additional classes are provided:

  • ofstream is derived from ostream and expands on it to handle file (disk) output.

  • ifstream is derived from istream and expands on it to handle file (disk) input.

 

"There are no pre-defined ofstream or ifstream objects.

It is your responsibility to create ofstream and ifstream objects in order to perform disk I/O.

You must also be sure to include the fstream.h header file..."

 

Because ofstream and ifstream are derived from classes you have been using throughout the course for console I/O, learning disk I/O is fairly easy.

 

 

Through inheritance, the functions and techniques used for console I/O also work for disk I/O

 

 

"Of course there are some additional things to learn because derived classes E-X-P-A-N-D on their base..."

 

Let's look at the steps involved in creating a disk file...

 

 

Creating a Disk File

(with examples)

 

 
  1. Include the required header file

 

#include <fstream.h>

 

  1. Declare an ofstream object

 

ofstream DiskOut;

 

"The name of the object is up to you (but be descriptive).

DiskOut can be used like cout - it is an object to which a stream of data may be sent..."

 

  1. Open the file

 

DiskOut.open("a:\\data\\myfile.dat");

 

"The open function is used to open a specified file on disk.

The double back-slashes are not typos - a single back-slash in C++ strings indicates an escape sequence so two are needed here to avoid confusion.

The name of a character array (containing the file name) could have been specified instead.

Other parameters  could have been passed, but default values are all we really need for now..."

 

  1. Test to see if the open was successful

 

if(!DiskOut.is_open())

  :

 

"The is_open function returns a non-zero (TRUE) value if the file is open.

You should display an error message if the open fails..."

 

  1. Send data to the file

 

DiskOut << "This goes to disk";

 

"Just treat the object like cout..."

 

  1. Close the file

 

DiskOut.close();

 

"If you forget to close the file, it will automatically be closed when the object goes out of scope..."

 

 

 

In the above example, default values were used when the file was opened.

By default, the file will be text mode - data that is int or float will be translated to ASCII text format when written to disk.

Text mode files can be processed by virtually all types of microcomputers and operating systems. They can also be created, viewed, and edited with any text editor (such as Notepad, Microsoft Word, or the Visual C++ Editor).

 

"There is a binary mode that stores data on disk in the same format it has in memory.

While it saves disk space and requires no translation during data transfer, it is not universally supported..."

 

Another default value used during open causes an existing file with the same name to be replaced.

 

"This could be dangerous..."

 

To override this default, code a second parameter when calling the open( ) function...

 

DiskOut.open("a:Myfile.dat",ios::noreplace);

 

"The ios::noreplace specification prevents an existing file with the same name from being replaced.

If a file with the same name exists, the open will fail.

The notation ios::noreplace means the value of noreplace (a symbolic constant) in the ios class (from which all I/O classes are derived)..."

 

There are several other ios flags that may be specified when opening a file. Some of the common ones are as follows:

ios::nocreate - the file must already exist or the open will fail

ios::app - if the file already exists, append records to the end the file

ios::binary - use binary mode

 

These flags can be used in combination by coding the bitwise OR operator (a single pipe) between them. For example,

 

DiskOut.open("a:Myfile.dat", ios::app | ios::binary);

 

"This file will be opened in binary mode with records being appended to the end of any existing file..."

 

Let's look at the steps involved in reading data from an existing disk file...

 

 

Reading Data from an Existing Disk File

(with examples)

 

 
  1. Include the required header file

 

#include <fstream.h>

 

  1. Declare an ifstream object

 

ifstream DiskIn;

 

"Once again, the name of the object is up to you.

DiskIn can be used like cin - it is an object from which data may be extracted..."

 

  1. Open the file

 

DiskIn.open("a:\\data\\myfile.dat");

 

"The file must already exist.

Appropriate ios flags could also be specified..."

 

  1. Test to see if the open was successful

 

if(!DiskIn.is_open())

  :

 

"If the file did not open successfully, you should display an error message..."

 

  1. Read data from the file

 

DiskIn >> DataFromDisk;

 

"Just treat the object like cin.

You can call member functions using dot notation such as DiskIn.getline( )..."

 

  1. Close the file

 

DiskIn.close();

 

 

 

When reading data from a disk file, there is always the possibility that no more data exists in the file.

To test for this end-of-file condition, you may use the eof( ) member function. It returns a non-zero (TRUE) value if no more data exists in the file.

 

Example

(Testing for end of file)

 

DiskIn >> DataFromDisk;

if(!DiskIn.eof())

{

process the data

}

 

"After attempting to read data from disk, you should test for end-of-file..."

 

 

Sample Program

 

**  There is no programming exercise for this lesson  **