📘 Reading and Writing Files in C++ (Text, Binary, and Directories)

File handling in C++ is done using the <fstream> and <filesystem> libraries. The <fstream> library handles reading and writing, while <filesystem> (C++17+) handles directory and file management.

[!NOTE] You can reference the following videos:


1. File Stream Classes

Class Purpose
ifstream Read from files
ofstream Write to files
fstream Read and write to files

Include <fstream> when working with these classes.


2. Writing and Reading Text Files

Text files store human-readable data (ASCII/UTF-8).

✏️ Writing to a Text File

#include <iostream>
#include <fstream>

int main() {
    std::ofstream outFile("example.txt");
    if (!outFile) {
        std::cerr << "Error opening file!" << std::endl;
        return 1;
    }

    outFile << "Hello, World!" << std::endl;
    outFile << "This is a sample text file." << std::endl;

    outFile.close();
    return 0;
}

📖 Reading from a Text File

#include <iostream>
#include <fstream>
#include <string>

int main() {
    std::ifstream inFile("example.txt");
    if (!inFile) {
        std::cerr << "Error opening file!" << std::endl;
        return 1;
    }

    std::string line;
    while (std::getline(inFile, line)) {
        std::cout << line << std::endl;
    }

    inFile.close();
    return 0;
}

3. Getting the Size of a File

You can determine file size using seekg() and tellg().

#include <iostream>
#include <fstream>

int main() {
    std::ifstream inFile("example.txt", std::ios::binary);
    if (!inFile) {
        std::cerr << "Error opening file!" << std::endl;
        return 1;
    }

    inFile.seekg(0, std::ios::end);
    std::streampos fileSize = inFile.tellg();
    std::cout << "File size: " << fileSize << " bytes" << std::endl;

    inFile.close();
    return 0;
}

4. Writing and Reading Binary Files

Binary files store raw byte data, which is more efficient for structured information.

✏️ Writing a Binary File

#include <iostream>
#include <fstream>

struct Data {
    int id;
    char name[20];
    double score;
};

int main() {
    std::ofstream outFile("data.bin", std::ios::binary);
    if (!outFile) {
        std::cerr << "Error opening file!" << std::endl;
        return 1;
    }

    Data record = {1, "Alice", 95.5};
    outFile.write(reinterpret_cast<char*>(&record), sizeof(record));

    outFile.close();
    return 0;
}

📖 Reading a Binary File (with EOF Handling)

#include <iostream>
#include <fstream>

struct Data {
    int id;
    char name[20];
    double score;
};

int main() {
    std::ifstream inFile("data.bin", std::ios::binary);
    if (!inFile) {
        std::cerr << "Error opening file!" << std::endl;
        return 1;
    }

    Data record;
    while (inFile.read(reinterpret_cast<char*>(&record), sizeof(record))) {
        std::cout << "ID: " << record.id
                  << "\nName: " << record.name
                  << "\nScore: " << record.score << "\n\n";
    }

    inFile.close();
    return 0;
}

5. Appending to Files

#include <fstream>
#include <iostream>

int main() {
    std::ofstream outFile("example.txt", std::ios::app);
    if (!outFile) {
        std::cerr << "Error opening file!" << std::endl;
        return 1;
    }

    outFile << "Appending new content." << std::endl;
    outFile.close();
    return 0;
}

6. Random Access in Binary Files

Use seekg() and seekp() to move the read/write pointers:

file.seekg(position, std::ios::beg); // Move read pointer
file.seekp(position, std::ios::beg); // Move write pointer

This lets you jump to specific positions in a file (e.g., record #N).


7. Iterating Over Files in a Directory

C++17’s <filesystem> makes directory traversal easy.

📁 Listing All Files in a Directory

#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;

int main() {
    std::string path = "."; // Current directory
    try {
        for (const auto& entry : fs::directory_iterator(path)) {
            std::cout << entry.path() << std::endl;
        }
    } catch (const fs::filesystem_error& e) {
        std::cerr << "Filesystem error: " << e.what() << std::endl;
    }

    return 0;
}

📂 Filtering .txt Files

#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;

int main() {
    std::string path = ".";

    for (const auto& entry : fs::directory_iterator(path)) {
        if (entry.path().extension() == ".txt") {
            std::cout << "Text file: " << entry.path().filename() << std::endl;
        }
    }

    return 0;
}

🔍 Recursive Directory Iteration

#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;

int main() {
    std::string path = ".";

    for (const auto& entry : fs::recursive_directory_iterator(path)) {
        std::cout << entry.path() << std::endl;
    }

    return 0;
}

8. Reading All .txt Files in a Directory

This combines directory iteration with file reading.

#include <iostream>
#include <fstream>
#include <filesystem>
#include <string>

namespace fs = std::filesystem;

int main() {
    std::string path = "."; // Current directory

    for (const auto& entry : fs::directory_iterator(path)) {
        if (entry.path().extension() == ".txt") {
            std::cout << "\n--- Reading: " << entry.path().filename() << " ---\n";

            std::ifstream inFile(entry.path());
            if (!inFile) {
                std::cerr << "Error opening file: " << entry.path() << std::endl;
                continue;
            }

            std::string line;
            while (std::getline(inFile, line)) {
                std::cout << line << std::endl;
            }

            inFile.close();
        }
    }

    return 0;
}

✅ Output Example

If your directory has:

example.txt
notes.txt
data.bin

Output:

--- Reading: example.txt ---
Hello, World!
This is a sample text file.

--- Reading: notes.txt ---
C++ File Handling Example

9. Summary

Operation Library Class / Function Notes
Write Text <fstream> ofstream Use <<
Read Text <fstream> ifstream Use getline()
Write Binary <fstream> ofstream Use write()
Read Binary <fstream> ifstream Use read()
Append <fstream> ofstream Open with std::ios::app
File Size <fstream> seekg(), tellg() Works for all file types
Random Access <fstream> seekg(), seekp() Jump to specific positions
Directory Iteration <filesystem> directory_iterator Traverse files and folders