Binary File I/O (fread/fwrite) & Random File Access (fseek/ftell)
Unit 5: Searching, Sorting, Dynamic Memory & File Handling • Problem Solving Using C
👨🏫 Professor's Mental Model: The Sequential Audio Tape vs Laser Turntable Arm
Text File purane jamane ki cassette tape jaisi hai jisme gana sunne ke liye reel ko shuru se aage tak chalana padta hai (Sequential Access). Binary File aur fseek ek modern DVD laser arm ya vinyl turntable jaisa hai: aap direct track 5 par laser ko drop kar sakte ho (Random Direct Access)! fread aur fwrite pure ke pure student structure record ko bina kisi conversion ke direct silicon RAM se disk platter par copy kar dete hain!
Academic Lecture Notes & Solved Study Pages
Unit 5 • Core Concepts, Step-by-Step Proofs & Notebook Solutions
1. Text Files vs Binary Files
Store human-readable ASCII/UTF-8 characters. The OS performs line-ending translations (e.g. converting `\n` to carriage return `\r\n` on Windows). Numbers are stored as digit characters ('1', '0', '0' takes 3 bytes).
Store raw binary data bytes exactly as structured in CPU RAM. No newline translation occurs. An integer `100` is stored in its raw 4-byte two's complement binary representation. Faster, compact, and immune to formatting corruption.
2. Block Record I/O: fread() and fwrite()
Ideal for persisting complete structs and arrays directly to disk:
Writes `count` items of `size` bytes from RAM into binary file.
Example: `fwrite(&s1, sizeof(struct Student), 1, fp);`
Reads `count` items of `size` bytes from binary file directly into RAM buffer.
Example: `fread(&s1, sizeof(struct Student), 1, fp);`
Returns the actual count of items successfully read (used to detect EOF).
3. Random File Access: fseek(), ftell() & rewind()
Allows non-sequential, direct jumping to any byte offset inside a file:
Repositions the internal file pointer to a new location.
1. `SEEK_SET` (0): Beginning of file.
2. `SEEK_CUR` (1): Current file pointer location.
3. `SEEK_END` (2): End of file.
Returns the current byte position of the file pointer relative to the start.
Useful trick to compute file size:
`fseek(fp, 0, SEEK_END); long file_size = ftell(fp);`
Resets file pointer back to the beginning (`SEEK_SET`), clearing all error indicators.
| Feature | Text Files (.txt) | Binary Files (.dat, .bin) |
|---|---|---|
| Storage Format | ASCII / Unicode characters | Exact binary bytes as stored in RAM |
| Human Readability | Easily readable in Notepad/Text editor | Unreadable garbage symbols in text editors |
| Line End Translation | Converts \n to \r\n on Windows | No translation: strictly raw byte stream |
| Storage Efficiency | Less efficient for numbers (e.g. 12345 takes 5B) | High: 32-bit int always takes exactly 4 Bytes |
| I/O Functions Used | fprintf, fscanf, fgetc, fgets | fread, fwrite, fseek, ftell |
| File Mode Flags | "r", "w", "a" | "rb", "wb", "ab", "rb+" |
Interactive Tested Code Example
#include <stdio.h>
#include <stdlib.h>
struct Student {
int id;
char name[20];
float marks;
};
int main(void) {
FILE *fp = fopen("students.dat", "wb+");
if (!fp) return 1;
struct Student s[3] = {
{101, "Alice", 89.5f},
{102, "Bob", 76.0f},
{103, "Charlie", 94.0f}
};
// 1. Write array of structures using fwrite
fwrite(s, sizeof(struct Student), 3, fp);
printf("Successfully written 3 student records to binary file.\n\n");
// 2. Random Access: Jump directly to Record 2 (Bob) using fseek
struct Student target;
fseek(fp, 1 * sizeof(struct Student), SEEK_SET); // Skip record 0
fread(&target, sizeof(struct Student), 1, fp);
printf("=== RANDOM ACCESS LOOKUP (RECORD 2) ===\n");
printf("ID: %d\n", target.id);
printf("Name: %s\n", target.name);
printf("Marks: %.1f%%\n\n", target.marks);
// 3. Compute Total File Size using ftell
fseek(fp, 0, SEEK_END);
long total_bytes = ftell(fp);
printf("Total Binary File Size: %ld Bytes (%zu Bytes per record)\n", total_bytes, sizeof(struct Student));
fclose(fp);
return 0;
}🎯 University Exam Scoring Blueprint
- In university exams, always specify the 3 seek flags: SEEK_SET (start), SEEK_CUR (current), SEEK_END (end).
- Explain the trick to find file size: fseek(fp, 0, SEEK_END); size = ftell(fp);.
- Highlight that binary modes append 'b' to mode strings: 'rb', 'wb', 'ab'.