100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
C++

File I/O with MFC

Reading and writing files in MFC using CFile, CStdioFile, and CArchive, plus handling file exceptions correctly.

Collections and UtilitiesIntermediate10 min readJul 10, 2026
Analogies

CFile: The Core File I/O Class

CFile wraps a Win32 file handle and provides an object-oriented interface for binary I/O. Open() accepts a filename and a combination of flags such as CFile::modeRead, CFile::modeWrite, CFile::modeCreate, and sharing flags like CFile::shareDenyWrite; Read() and Write() move raw bytes between the file and a buffer, and Seek() repositions the file pointer using CFile::begin, CFile::current, or CFile::end as the reference point. Unlike the older C runtime fopen/fread family, CFile methods throw CFileException on failure rather than returning error codes, which integrates naturally with C++ exception handling.

🏏

Cricket analogy: Opening a CFile with modeCreate versus modeRead is like a groundskeeper deciding whether to prepare a brand-new pitch for a Test match or simply inspect the existing one before play, each requiring a different set of flags and permissions.

cpp
CFile file;
CFileException fe;
if (!file.Open(_T("scores.dat"),
                CFile::modeCreate | CFile::modeWrite | CFile::shareExclusive,
                &fe))
{
    TRACE(_T("Failed to open file, cause = %d\n"), fe.m_cause);
    return;
}

int nScore = 87;
file.Write(&nScore, sizeof(nScore));
file.Seek(0, CFile::begin);
int nCheck = 0;
file.Read(&nCheck, sizeof(nCheck));
file.Close();

Buffered I/O with CStdioFile

CStdioFile derives from CFile and adds text-oriented, buffered line I/O layered on top of the C runtime's stream functions. ReadString() reads one line at a time into a CString until end-of-file, and WriteString() writes a CString followed by whatever line terminator convention the file uses, making CStdioFile well suited for log files, CSV exports, and configuration files where you think in terms of lines rather than raw byte offsets.

🏏

Cricket analogy: ReadString() pulling one line at a time is like a commentator reading a ball-by-ball text commentary feed one delivery at a time rather than ingesting the entire innings transcript as one undivided block.

Structured I/O with CArchive

CArchive wraps a CFile to add buffering and typed, structured I/O for use with MFC's serialization framework. You construct a CArchive in either CArchive::store or CArchive::load mode, then use operator<< and operator>> to write and read built-in types, CString, and CObject-derived objects, checking IsStoring() or IsLoading() inside a Serialize() override to decide which direction to run. CArchive maintains its own internal buffer separate from CFile's, so calling Close() (or letting the destructor run) is essential to flush pending writes to disk.

🏏

Cricket analogy: IsStoring() versus IsLoading() is like a scorer's app switching between 'live entry mode' during a match and 'replay mode' when reviewing a past Ashes Test, using the same scoresheet format for both directions.

Error Handling in File Operations

CFile methods signal failure by throwing a CFileException object, whose m_cause member identifies the specific problem: CFileException::fileNotFound, CFileException::accessDenied, CFileException::sharingViolation, and CFileException::diskFull are common values. Wrapping file operations in a try/catch(CFileException* e) block (or the older TRY/CATCH macros in legacy code) lets you branch on m_cause to give the user an accurate message, and you must call e->Delete() when using the macro-based catch to free the exception object MFC allocated on the heap.

🏏

Cricket analogy: Branching on m_cause is like an umpire distinguishing between different reasons a delivery is called dead — a no-ball, a bad light stoppage, or a boundary rope infringement — each requiring a different ruling.

Use CFile::modeCreate combined with CFile::modeNoTruncate when you want to create a file only if it does not already exist, or open it without wiping existing contents if it does. Without modeNoTruncate, modeCreate always truncates an existing file to zero length, which can silently destroy data if used carelessly on a file that already has content.

Forgetting to call Close() on a CFile or CArchive (or letting an exception unwind past the point where it would be closed) leaves the underlying Win32 file handle open. On Windows, an open handle with exclusive or deny-write sharing will cause subsequent attempts to open the same file, even from the same process, to fail with a sharing violation.

  • CFile provides object-oriented binary file I/O with Open, Read, Write, and Seek, throwing CFileException on failure.
  • CStdioFile adds buffered, line-oriented text I/O via ReadString and WriteString.
  • CArchive wraps a CFile to provide typed, structured I/O used by MFC's serialization framework.
  • IsStoring() and IsLoading() let a single Serialize() method handle both save and load directions.
  • CFileException::m_cause identifies specific failure reasons like fileNotFound, accessDenied, and diskFull.
  • modeCreate truncates an existing file unless combined with modeNoTruncate.
  • Always Close() files and archives explicitly to avoid lingering sharing violations.

Practice what you learned

Was this page helpful?

Topics covered

#MFCMicrosoftFoundationClassesStudyNotes#MicrosoftTechnologies#FileIOWithMFC#File#MFC#CFile#Core#StudyNotes#SkillVeris#ExamPrep