6.1.1 Opening, Closing, and Creating Files

The CFile Class - MFC

2025-10-31

Written by: Jeff Prosise

Files can be opened with CFile in either of two ways. The first option is to construct an uninitialized CFile object and call CFile::Open. The following code fragment uses this technique to open a file named File.txt with read/write access. Because no path name is provided in the function’s first parameter, Open will fail unless the file is located in the current directory:

CFile file;
file.Open (_T ("File.txt"), CFile::modeReadWrite);

CFile::Open returns a BOOL indicating whether the operation was successful. The following example uses that return value to verify that the file was successfully opened:

CFile file;
    if (file.Open (_T ("File.txt"), CFile::modeReadWrite)) {
        // It worked!
}

A nonzero return value means the file was opened; 0 means it wasn’t. If CFile::Open returns 0 and you want to know why the call failed, create a CFileException object and pass its address to Open in the third parameter:

CFile file;
CFileException e;
if (file.Open (_T ("File.txt"), CFile::modeReadWrite, &e)) {
    // It worked!
}
else {
    // Open failed. Tell the user why.
    e.ReportError ();
}

If Open fails, it initializes the CFileException object with information describing the nature of the failure. ReportError displays an error message based on that information. You can find out what caused the failure by examining the CFileException’s public m_cause data member. The documentation for CFileException contains a complete list of error codes. The second option is to open the file using CFile’s constructor. Rather than construct an empty CFile object and call Open, you can create a CFile object and open a file in one step like this:

CFile file (_T ("File.txt"), CFile::modeReadWrite);

If the file can’t be opened, CFile’s constructor throws a CFileException. Therefore, code that opens files using CFile::CFile normally uses try and catch blocks to trap errors:

try {
    CFile file (_T ("File.txt"), CFile::modeReadWrite);
}
catch (CFileException* e) {
    // Something went wrong.
    e->ReportError ();
    e->Delete ();
}

It’s up to you to delete the CFileException objects MFC throws to you. That’s why this example calls Delete on the exception object after processing the exception. The only time you don’t want to call Delete is the rare occasion when you use throw to rethrow the exception. To create a new file rather than open an existing one, include a CFile::modeCreate flag in the second parameter to CFile::Open or the CFile constructor:

CFile file (_T ("File.txt"), CFile::modeReadWrite | CFile::modeCreate);

If a file created this way already exists, its length is truncated to 0. To create the file if it doesn’t exist or to open it without truncating it if it does exist, include a CFile::modeNoTruncate flag as well:

CFile file (_T ("File.txt"), CFile::modeReadWrite | CFile::modeCreate | CFile::modeNoTruncate);

An open performed this way almost always succeeds because the file is automatically created for you if it doesn’t already exist. By default, a file opened with CFile::Open or CFile::CFile is opened for exclusive access, which means that no one else can open the file. If desired, you can specify a sharing mode when opening the file to explicitly grant others permission to access the file, too. Here are the four sharing modes that you can choose from:

Sharing ModeDescription
CFile::shareDenyNoneOpens the file nonexclusively
CFile::shareDenyReadDenies read access to other parties
CFile::shareDenyWriteDenies write access to other parties
CFile::shareExclusiveDenies both read and write access to other parties(default)

In addition, you can specify any one of the following three types of read/write access:

Access ModeDescription
CFile::modeReadWriteRequests read and write access
CFile::modeReadRequests read access only
CFile::modeWriteRequests write access only

A common use for these options is to allow any number of clients to open a file for reading but to deny any client the ability to write to it:

CFile file (_T ("File.txt"), CFile::modeRead ¦ CFile::shareDenyWrite);

If the file is already open for writing when this statement is executed, the call will fail and CFile will throw a CFileException with m_cause equal to CFileException::sharingViolation. An open file can be closed in two ways. To close a file explicitly, call CFile::Close on the corresponding CFile object:

file.Close ();

If you’d prefer, you can let CFile’s destructor close the file for you. The class destructor calls Close if the file hasn’t been closed already. This means that a CFile object created on the stack will be closed automatically when it goes out of scope. In the following example, the file is closed the moment the brace marking the end of the try block is reached:

try {
    CFile file (_T ("File.txt"), CFile::modeReadWrite);
    // CFile::~CFile closes the file.
}

One reason programmers sometimes call Close explicitly is to close the file that is currently open so that they can open another file using the same CFile object

Ref