Skip to main content

Command Palette

Search for a command to run...

File system

Updated
•9 min read•View as Markdown

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

More from this blog