10.1 Files

The Microsoft Foundation Class Library provides the CFile class for general-purpose binary file operations. The CStdioFile and CMemFile classes are derived from CFile to provide more specialized file services.

In the Microsoft Foundation Class Library, the most common way to open a file is to go through a two-stage process.

·To open a file:

1.Create the file object without specifying a path or permission flags.

You usually create a file object by declaring a CFile variable on the frame.

2.Call the Open member function for the file object, supplying a path and permission flags.

Open will return TRUE if the file was opened successfully, or FALSE if the specified file could not be opened.

The open flags specify which permissions, such as read-only, you want for the file. The possible flag values are defined as enumerated constants within the CFile class, so they are qualified with “CFile::”, as in CFile::modeRead. Use the CFile::modeCreate flag if you want to create the file.

The following example shows how to create a new file with read/write permission (replacing any previous file with the same path):

char* pszFileName = "\\test\\myfile.dat";

CFile myFile;

if ( ! myFile.Open( pszFileName,

CFile::modeCreate | CFile::modeReadWrite ) )

{

TRACE( "Can't open file %s\n",pszFileName );

}

·To read from and write to the file:

Use the Read and Write member functions to read and write data in the file.

The Seek member function is also available for moving to a specific offset within the file.

Read takes a pointer to a buffer and a UINT specifying the number of bytes to read or write and returns a UINT with the actual number of bytes that were processed. Write takes the same arguments but does not return the number of bytes written. If the requested number of bytes can't be read or written, an exception is thrown. If you have a valid CFile object, you can read or write to it with code similar to the following:

char buffer[256];

UINT actual = 0;

myFile.Write( buffer, sizeof( buffer ) );

myFile.Seek( 0, CFile::begin );

actual = myFile.Read( buffer, sizeof( buffer ) );

·To close a file:

Use the Close member function. This function closes the file system file and flushes buffers if neccessary.

If you allocated the CFile object on the frame (as in the examples above) it will be automatically destroyed when it goes out of scope. It is important to close the file before the object is deleted. Note that deleting the CFile object does not delete the physical file in the file system.

·To get file status:

Use the CFile object to get and set information about a file. One useful application is to use the CFile static member function GetStatus to determine if a file exists. GetStatus will return FALSE if the specified file does not exist.

Thus, you could use the result of GetStatus to determine whether to use the CFile::modeCreate flag when opening a file, as shown by the following example.

CFile theFile;

char* szFileName = "c:\\test\\myfile.dat";

BOOL fOpenOK;

CFileStatus status;

// GetStatus will return TRUE if file exists,

// or FALSE if it doesn't exist

if( CFile::GetStatus( szFileName, status ) )

{

// Open the file without the Create flag

fOpenOK = theFile.Open( szFileName,

CFile::modeWrite );

}

else

{

// Open the file with the Create flag

fOpenOK = theFile.Open( szFileName,

CFile::modeCreate | CFile::modeWrite );

}