C Binary File I/O, Struct Serialization & fseek() Positioning Masterclass

โšก C (C17 / C23 Standard) ๐ŸŸข Lesson 37 ๐Ÿ“‚ Phase 14: File Handling & I/O Streams ๐Ÿ“… 2026 Comprehensive Master Edition
๐Ÿ“Œ Covered in this in-depth guide: Binary File Modes (rb, wb) ยท fwrite() & fread() ยท Struct Serialization ยท Random Access Positioning (fseek, ftell, rewind) ยท SEEK_SET / SEEK_CUR / SEEK_END

Welcome to Phase 14 (Chapter 37): C Binary File I/O, Struct Serialization & fseek() Positioning Masterclass! While text files format values into human-readable ASCII strings, binary files write exact RAM byte images directly to disk. In this guide, you will master fwrite(), fread(), binary struct serialization, and random-access positioning with fseek().

1Text Files vs Binary Files Comparison

Binary files store raw memory byte blocks without string conversion overhead.

FeatureText Files ("r", "w", "a")Binary Files ("rb", "wb", "ab")
Data StorageASCII / UTF-8 CharactersExact RAM Raw Bytes
Storage SizeVariable (Integer 1234567 = 7 bytes)Fixed (32-bit int = 4 bytes)
Processing SpeedSlower (Requires parsing formatted text)Ultra Fast (Direct RAM-to-Disk block copy)
Newline TranslationOS converts \n to \r\n on WindowsNo translation (Pure byte fidelity)
2fwrite(), fread() & Binary Struct Serialization

Binary I/O functions move blocks of memory between RAM and disk:

Binary I/O Function Signatures:

โ€ข size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);

โ€ข size_t fread(void *ptr, size_t size, size_t count, FILE *stream);

Passing &structInstance writes the entire C structure (including internal member bytes) in one single atomic I/O operation!

3Random Access File Positioning (fseek, ftell, rewind)

By default, file reading and writing happen sequentially. Functions in <stdio.h> allow moving the File Position Indicator to any arbitrary byte location:

File Byte Offset Positioning Indicator in RAM/Disk: Byte Index: 0 100 200 300 400 500 (EOF) File Buffer: [ HEADER | RECORD 1 | RECORD 2 | RECORD 3 ] โ–ฒ โ–ฒ โ–ฒ โ”‚ โ”‚ โ”‚ SEEK_SET SEEK_CUR SEEK_END (File Start) (Current Position) (End of File)

โ€ข fseek(fp, offset, origin): Moves file cursor. origin can be SEEK_SET (0), SEEK_CUR (current), or SEEK_END (file end).
โ€ข ftell(fp): Returns current byte offset location from file start.
โ€ข rewind(fp): Resets file pointer back to index 0.

4Comprehensive Production Code Example
C โ€” Binary Database Indexing & Random Lookupโ–ถ Run Code in C Compiler
#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int id;
    char name[30];
    double balance;
} Account;

int main(void) {
    const char *db_file = "bank_accounts.dat";

    Account accounts[3] = {
        {101, "Ravi Kumar", 45000.50},
        {102, "Anitha Roy", 89200.75},
        {103, "Kiran Sharma", 12300.00}
    };

    FILE *fp = fopen(db_file, "wb");
    if (!fp) { perror("Failed to create db"); return 1; }
    fwrite(accounts, sizeof(Account), 3, fp);
    fclose(fp);
    printf("Successfully serialized 3 Account structs to binary file.\n");

    fp = fopen(db_file, "rb");
    if (!fp) { perror("Failed to open db"); return 1; }

    fseek(fp, 0, SEEK_END);
    long fileSize = ftell(fp);
    printf("Total Binary File Size: %ld Bytes (%ld Accounts)\n", fileSize, fileSize / sizeof(Account));

    int targetIndex = 1;
    long offset = targetIndex * sizeof(Account);
    fseek(fp, offset, SEEK_SET);

    Account found;
    if (fread(&found, sizeof(Account), 1, fp) == 1) {
        printf("\n--- DIRECT RECORD LOOKUP (Index %d) ---\n", targetIndex);
        printf("ID: %d | Name: %s | Balance: $%.2f\n", found.id, found.name, found.balance);
    }
    fclose(fp);
    return 0;
}
5Technical FAQs

Q1: Why are binary files not portable across different CPU architectures?

Binary files write raw RAM memory bytes. Different CPUs have different Endianness (Little-Endian Intel vs Big-Endian Network) and struct padding alignment rules.

Q2: How do you find the exact byte size of a file in C?

Use fseek(fp, 0, SEEK_END); long size = ftell(fp); rewind(fp);.

Q3: What does the return value of fread() and fwrite() indicate?

They return the number of elements successfully read or written, NOT byte counts.

Q4: Why specify "b" in fopen() mode string ("rb", "wb")?

On Windows operating systems, opening files without "b" treats them as text files, automatically altering \r\n bytes which corrupts raw binary images.

Q5: What is struct padding risk during binary serialization?

Compilers insert padding hole bytes inside structures for RAM memory alignment. Writing raw structs writes these padding bytes, wasting disk space.