C Binary Files

Learn how to work with binary files in C programming

💾 Binary Files in C

Binary files store data in binary format, making them efficient for storing structured data, images, and executable files. Use fwrite() and fread() functions to handle binary data with precise control over file operations.


#include <stdio.h>

int main() {
    FILE *file = fopen("data.bin", "wb");
    int number = 42;
    fwrite(&number, sizeof(int), 1, file);
    fclose(file);
    return 0;
}
                                    

Binary File Operations

💾

fwrite()

Write binary data to files

fwrite(&data, size, count, file);
📥

fread()

Read binary data from files

fread(&data, size, count, file);
🎯

fseek()

Move file pointer to specific position

fseek(file, offset, SEEK_SET);
📍

ftell()

Get current file pointer position

long pos = ftell(file);

🔹 Writing Binary Data

The fwrite() function efficiently writes binary data directly to files without text conversion. Binary mode preserves exact byte representations, making it ideal for storing structured data, integers, or complex objects. fwrite() accepts a pointer to data, element size, element count, and file pointer, writing all data in one operation. Always verify fwrite() return value to confirm all elements were written successfully, handle write failures appropriately, and use binary mode when precision and efficiency matter.

#include <stdio.h>

int main() {
    FILE *file;
    int numbers[] = {10, 20, 30, 40, 50};
    int count = 5;
    
    file = fopen("numbers.bin", "wb");
    
    if (file != NULL) {
        // Write array of integers
        size_t written = fwrite(numbers, sizeof(int), count, file);
        
        printf("Written %zu integers to binary file\n", written);
        fclose(file);
    } else {
        printf("Error creating binary file!\n");
    }
    
    return 0;
}

Output:

Written 5 integers to binary file

🔹 Reading Binary Data

The fread() function efficiently reads binary data from files into memory structures. Binary reading preserves exact byte values without text conversion, perfect for retrieving stored integers, floating-point numbers, or complex structures. fread() reads a specified number of elements of given size into a buffer. Always check return values to verify how many elements were actually read, handle end-of-file conditions properly, and ensure sufficient buffer space before reading to prevent buffer overflows.

#include <stdio.h>

int main() {
    FILE *file;
    int numbers[5];
    int i;
    
    file = fopen("numbers.bin", "rb");
    
    if (file != NULL) {
        // Read array of integers
        size_t read = fread(numbers, sizeof(int), 5, file);
        
        printf("Read %zu integers from binary file:\n", read);
        for (i = 0; i < read; i++) {
            printf("Number %d: %d\n", i + 1, numbers[i]);
        }
        
        fclose(file);
    } else {
        printf("Error opening binary file!\n");
    }
    
    return 0;
}

Output:

Read 5 integers from binary file:
Number 1: 10
Number 2: 20
Number 3: 30
Number 4: 40
Number 5: 50

🔹 Binary File Modes

Different file modes control how binary files are opened and accessed during operations. Mode rb opens files for reading binary data, wb creates or truncates files for writing binary data, ab appends binary data to existing files, and rb+ or wb+ allows both reading and writing. Choosing the correct mode is essential for preventing data corruption and ensuring expected program behavior. Always match your intended operation with the appropriate file mode to avoid accidental data loss or access errors.

Binary File Modes:

  • "rb" - Read binary file
  • "wb" - Write binary file (overwrites existing)
  • "ab" - Append to binary file
  • "rb+" - Read and write binary file
  • "wb+" - Create binary file for read/write
#include <stdio.h>

int main() {
    FILE *file;
    float temperature = 23.5;
    float readTemp;
    
    // Write binary data
    file = fopen("temp.bin", "wb");
    if (file != NULL) {
        fwrite(&temperature, sizeof(float), 1, file);
        fclose(file);
        printf("Temperature %.1f written to binary file\n", temperature);
    }
    
    // Read binary data
    file = fopen("temp.bin", "rb");
    if (file != NULL) {
        fread(&readTemp, sizeof(float), 1, file);
        fclose(file);
        printf("Temperature %.1f read from binary file\n", readTemp);
    }
    
    return 0;
}

🔹 Working with Structures

Storing and retrieving structures in binary files enables efficient persistence of complex data types. Use fwrite() to save entire structures to files, then use fread() to restore them, preserving all structure members and their values. This approach works for arrays of structures, nested structures, and complex data organizations. Be aware of potential platform differences in structure layout and size, consider endianness issues for portability, and implement version checking if structure definitions change over time to maintain backward compatibility.

#include <stdio.h>
#include <string.h>

struct Person {
    int id;
    char name[50];
    int age;
    float salary;
};

int main() {
    FILE *file;
    struct Person person1 = {1, "Alice", 25, 50000.0};
    struct Person person2 = {2, "Bob", 30, 60000.0};
    struct Person readPerson;
    
    // Write structures to binary file
    file = fopen("people.bin", "wb");
    if (file != NULL) {
        fwrite(&person1, sizeof(struct Person), 1, file);
        fwrite(&person2, sizeof(struct Person), 1, file);
        fclose(file);
        printf("Person records written to binary file\n");
    }
    
    // Read structures from binary file
    file = fopen("people.bin", "rb");
    if (file != NULL) {
        printf("\nReading person records:\n");
        while (fread(&readPerson, sizeof(struct Person), 1, file) == 1) {
            printf("ID: %d, Name: %s, Age: %d, Salary: %.2f\n",
                   readPerson.id, readPerson.name, 
                   readPerson.age, readPerson.salary);
        }
        fclose(file);
    }
    
    return 0;
}

Output:

Person records written to binary file

Reading person records:
ID: 1, Name: Alice, Age: 25, Salary: 50000.00
ID: 2, Name: Bob, Age: 30, Salary: 60000.00

🔹 File Positioning

The fseek() and ftell() functions enable random access to specific file locations. fseek() moves the file pointer to any position, enabling you to read or write at specific locations without reading everything sequentially. ftell() returns the current file position, useful for tracking location and calculating offsets. These functions are essential for implementing efficient file access patterns, enabling database-like operations on files, and optimizing performance when working with specific file sections.

#include <stdio.h>

int main() {
    FILE *file;
    int numbers[] = {100, 200, 300, 400, 500};
    int value;
    long position;
    
    // Write data
    file = fopen("random.bin", "wb");
    if (file != NULL) {
        fwrite(numbers, sizeof(int), 5, file);
        fclose(file);
    }
    
    // Random access reading
    file = fopen("random.bin", "rb");
    if (file != NULL) {
        // Read 3rd number (index 2)
        fseek(file, 2 * sizeof(int), SEEK_SET);
        fread(&value, sizeof(int), 1, file);
        printf("3rd number: %d\n", value);
        
        // Get current position
        position = ftell(file);
        printf("Current position: %ld bytes\n", position);
        
        // Go to beginning and read first number
        fseek(file, 0, SEEK_SET);
        fread(&value, sizeof(int), 1, file);
        printf("1st number: %d\n", value);
        
        fclose(file);
    }
    
    return 0;
}

Output:

3rd number: 300
Current position: 12 bytes
1st number: 100

🧠 Test Your Knowledge

What does the "b" in "wb" file mode stand for?