File system
1. Sequential Access
What is Sequential Access?
Sequential access means accessing data one record after another, in a fixed order.
Think about a book:
Page 1
Page 2
Page 3
Page 4
Page 5
If you want to reach Page 4, you normally move through:
Page 1 → Page 2 → Page 3 → Page 4
This is called sequential access.
Sequential Access in Files
Suppose a file contains:
students.txt
101 Amit
102 Rahul
103 Neha
104 Priya
105 Rohit
If we read the file sequentially:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream file("students.txt");
int roll;
string name;
while (file >> roll >> name) {
cout << roll << " " << name << endl;
}
file.close();
return 0;
}
Output:
101 Amit
102 Rahul
103 Neha
104 Priya
105 Rohit
The records are accessed one after another:
101 Amit
↓
102 Rahul
↓
103 Neha
↓
104 Priya
↓
105 Rohit
This is Sequential File Access.
File Pointer in Sequential Access
A file has a logical file position/pointer that indicates where the next read or write will occur.
Initially:
101 Amit
↑
pointer
After reading the first record:
101 Amit | 102 Rahul
↑
pointer
After reading the second record:
101 Amit | 102 Rahul | 103 Neha
↑
pointer
The position moves forward as data is read.
When is Sequential Access Useful?
Sequential access is useful when you need to process the entire file.
For example:
Student Records
↓
Read Student 1
↓
Read Student 2
↓
Read Student 3
↓
...
↓
Read Student 1000
If you want to calculate:
Total marks
Average marks
Maximum marks
Minimum marks
for all students, sequential access is very suitable.
Disadvantage of Sequential Access
Suppose a file contains 1,000,000 records, and you only want record number 999,999.
Sequential access may require:
Record 1 → Record 2 → Record 3 → ... → Record 999,999
This can be inefficient.
For such situations, random access is more suitable.
2. Random Access
What is Random Access?
Random access means directly accessing a particular location in a file without reading all the previous data.
Think about a book.
If someone says:
Open Page 500.
You do not read:
Page 1 → Page 2 → Page 3 → ... → Page 500
You directly open:
Page 500
↑
Direct Access
That is random access.
Random Access in C++
C++ provides functions for moving around inside a file.
The important ones are:
seekg()
seekp()
tellg()
tellp()
seekg()
g stands for get.
It moves the input/read position of a file.
Example:
file.seekg(10);
This moves the read pointer to position 10.
Example
Suppose a file contains:
A B C D E F G H I J
Positions:
Character: A B C D E F G H I J
Position: 0 1 2 3 4 5 6 7 8 9
Now:
file.seekg(5);
The pointer moves directly to:
A B C D E F G H I J
↑
F
If we now read one character:
char ch;
file.get(ch);
cout << ch;
Output:
F
We directly moved to F.
seekg() with ios::beg
file.seekg(10, ios::beg);
Meaning:
Move 10 positions from the beginning of the file.
Beginning
|
↓
0 1 2 3 4 5 6 7 8 9 10
↑
pointer
seekg() with ios::cur
file.seekg(10, ios::cur);
Meaning:
Move 10 positions from the current position.
seekg() with ios::end
file.seekg(-10, ios::end);
Meaning:
Move 10 positions backward from the end of the file.
tellg()
tellg() tells us the current read position.
Example:
cout << file.tellg();
If the current position is 20:
20
So remember:
seekg() → Move the read pointer
tellg() → Tell the current read position
Random Access with Records
This is one of the most important practical uses.
Suppose:
struct Student {
int roll;
char name[20];
float marks;
};
Suppose:
sizeof(Student) = 32 bytes
Then the file could look like:
| Student 0 | Student 1 | Student 2 | Student 3 | Student 4 |
0 32 64 96 128
If you want Student 3, you can directly move to:
file.seekg(3 * sizeof(Student), ios::beg);
That means:
3 × 32 = 96 bytes
So the pointer moves directly to Student 3.
Then:
Student s;
file.read((char*)&s, sizeof(s));
This is random access.
Sequential vs Random Access
| Sequential Access | Random Access |
|---|---|
| Accesses data one by one | Directly accesses a specific location |
| Data is accessed in order | Data can be accessed in any order |
| Suitable for processing the complete file | Suitable for accessing specific records |
| Simple to implement | Requires file-position functions |
| Example: 1 → 2 → 3 → 4 | Example: directly access record 500 |
Easy way to remember
Sequential = Train
Station 1 → 2 → 3 → 4
Random = Flight
Delhi ─────────→ London
3. Binary File Operations
Now let's understand Binary Files.
There are two common ways of storing file data:
FILE
|
+-------+-------+
| |
Text Binary
Text File
A text file stores data in a human-readable form.
For example:
student.txt
101 Amit 90
102 Rahul 85
103 Neha 92
If you open this file using Notepad or a text editor, you can easily understand the content.
Binary File
A binary file stores data as raw bytes.
For example, when an integer is stored in binary form, its underlying bytes are stored rather than the characters representing the number.
Therefore, if you open a binary file in a normal text editor, you may see unreadable or strange characters.
Common binary file extensions include:
.dat
.bin
The extension itself does not make a file binary; the way the data is written and read determines how it is interpreted.
Why Use Binary Files?
Binary files are useful because:
1. They store raw data
For example:
int
float
char arrays
structures
can be stored as bytes.
2. They avoid text conversion
With text files, values are converted to characters.
With binary files, we can work directly with their byte representation.
3. They work well with fixed-size records
This is especially useful when combined with random access.
Opening a Binary File
Use:
ios::binary
Example:
ofstream file("student.dat", ios::binary);
For reading:
ifstream file("student.dat", ios::binary);
write() Function
The write() function is commonly used to write raw bytes to a binary file.
Syntax:
file.write((char*)&variable, sizeof(variable));
Let's understand it.
Suppose:
int age = 25;
Then:
file.write((char*)&age, sizeof(age));
&age
Means:
Address of
age.
(char*)&age
Treat the memory of age as a sequence of bytes.
sizeof(age)
Tells the program how many bytes should be written.
Complete Binary Write Example
#include <iostream>
#include <fstream>
using namespace std;
int main() {
int age = 25;
ofstream file("data.dat", ios::binary);
file.write((char*)&age, sizeof(age));
file.close();
return 0;
}
The flow is:
age = 25
↓
Memory
↓
write()
↓
data.dat
read() Function
The read() function is used to read raw bytes from a binary file.
Example:
file.read((char*)&age, sizeof(age));
Complete example:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
int age;
ifstream file("data.dat", ios::binary);
file.read((char*)&age, sizeof(age));
cout << age;
file.close();
return 0;
}
Output:
25
The flow is:
Binary File
↓
read()
↓
Memory
↓
age
Binary File with a Structure
This is an important example.
Suppose:
struct Student {
int roll;
char name[20];
float marks;
};
Create an object:
Student s = {101, "Amit", 95.5};
We can write it to a binary file:
ofstream file("student.dat", ios::binary);
file.write((char*)&s, sizeof(s));
file.close();
The structure's object representation is written as bytes.
Reading the Structure
Student s;
ifstream file("student.dat", ios::binary);
file.read((char*)&s, sizeof(s));
cout << s.roll << endl;
cout << s.name << endl;
cout << s.marks << endl;
file.close();
Output:
101
Amit
95.5
read() vs write()
This is extremely easy to remember:
write()
RAM ─────────→ File
read()
File ─────────→ RAM
So:
write() = store data
read() = retrieve data
Binary File + Random Access
Now let's connect the concepts.
Suppose a binary file contains:
| Student 0 | Student 1 | Student 2 | Student 3 | Student 4 |
If every Student record has a fixed size:
sizeof(Student) = 40 bytes
Then:
Student 0 → 0 bytes
Student 1 → 40 bytes
Student 2 → 80 bytes
Student 3 → 120 bytes
Student 4 → 160 bytes
To directly access Student 3:
file.seekg(3 * sizeof(Student), ios::beg);
Then:
file.read((char*)&s, sizeof(s));
The process is:
Binary File
------------------------------------------------
| S0 | S1 | S2 | S3 | S4 |
↑
seekg()
|
read()
|
↓
Student s
This is the combination of:
Binary File + Random Access
and it is a very important concept in file handling.
Final Summary
Remember these three concepts like this:
1. Sequential Access
1 → 2 → 3 → 4 → 5
One record after another.
2. Random Access
1 → 2 → 3
─────────→ 500
Directly jump to the required position.
Important functions:
seekg()
seekp()
tellg()
tellp()
3. Binary File
Object
↓
Raw Bytes
↓
Binary File
Important functions:
write() → File
read() → Memory
and:
ios::binary
is used to open a file in binary mode.
One-line memory trick:
Sequential = One by One
Random = Direct Jump
Binary = Raw Bytes