Lesson 15 of 2010 min read
Binary File Handling in Python (Pickle Module)
Prerequisites: Text file handling, lists, dictionaries, exception handling
1. What Are Binary Files?
- Binary files store data in binary format (bytes), not human-readable text., They can store any Python object: lists, dictionaries, tuples, class objects., Binary files are not readable in a text editor, they appear as garbled characters., They are platform-independent (no line-ending translation like text files)., Faster to read/write for complex data structures.
2. The pickle Module
The pickle module converts Python objects to byte streams and back.
- Pickling (Serialization): Converting a Python object to a byte stream and writing it to a file.
- Unpickling (Deserialization): Reading a byte stream from a file and converting it back to a Python object.
import pickle
Key Functions
| Function | Purpose |
|---|---|
pickle.dump(object, file) |
Write (pickle) an object to a binary file |
pickle.load(file) |
Read (unpickle) an object from a binary file |
3. File Modes for Binary Files
| Mode | Description |
|---|---|
"rb" |
Read binary |
"wb" |
Write binary (creates new / overwrites) |
"ab" |
Append binary |
"rb+" |
Read and write binary (file must exist) |
"wb+" |
Write and read binary (overwrites) |
"ab+" |
Append and read binary |
4. Writing to Binary Files: dump
import pickle
# Writing a single object
data = [10, 20, 30, 40, 50]
with open("data.dat", "wb") as f:
pickle.dump(data, f)
print("Data written to file.")
Writing Multiple Objects
import pickle
with open("multi.dat", "wb") as f:
pickle.dump([1, 2, 3], f) # First object
pickle.dump("Hello", f) # Second object
pickle.dump({"a": 1, "b": 2}, f) # Third object
print("Multiple objects written.")
5. Reading from Binary Files: load
import pickle
with open("data.dat", "rb") as f:
data = pickle.load(f)
print(data)
# Output: [10, 20, 30, 40, 50]
Reading Multiple Objects
import pickle
with open("multi.dat", "rb") as f:
obj1 = pickle.load(f) # [1, 2, 3]
obj2 = pickle.load(f) # 'Hello'
obj3 = pickle.load(f) # {'a': 1, 'b': 2}
print(obj1)
print(obj2)
print(obj3)
# Output:
# [1, 2, 3]
# Hello
# {'a': 1, 'b': 2}
6. Handling EOFError When Reading
When reading a binary file, you don't know how many objects are stored. Calling load after all objects are read raises EOFError.
Pattern: Read All Objects Until EOFError
import pickle
with open("multi.dat", "rb") as f:
try:
while True:
obj = pickle.load(f)
print(obj)
except EOFError:
print("--- End of file reached ---")
# Output:
# [1, 2, 3]
# Hello
# {'a': 1, 'b': 2}
# --- End of file reached ---
This pattern is essential for exams and is used in almost every binary file reading program.
7. Difference: Text Files vs Binary Files
| Feature | Text File | Binary File |
|---|---|---|
| Module | Built-in (no import) | import pickle |
| Mode | "r", "w", "a" |
"rb", "wb", "ab" |
| Write method | write, writelines |
pickle.dump |
| Read method | read, readline, readlines |
pickle.load |
| Data type | Strings only | Any Python object |
| Readability | Human-readable | Not human-readable |
| End of file | Returns empty string "" |
Raises EOFError |
Practice Programs
Program 1: Write a List to Binary File
import pickle
# Create a list and write to binary file
marks = [85, 92, 78, 95, 88]
with open("marks.dat", "wb") as f:
pickle.dump(marks, f)
print("List written to marks.dat")
print("Data:", marks)
# Output:
# List written to marks.dat
# Data: [85, 92, 78, 95, 88]
Program 2: Read from Binary File
import pickle
# Read the list from binary file
with open("marks.dat", "rb") as f:
marks = pickle.load(f)
print("Data read from file:", marks)
print("Total marks:", sum(marks))
print("Average:", sum(marks) / len(marks))
# Output:
# Data read from file: [85, 92, 78, 95, 88]
# Total marks: 438
# Average: 87.6
Program 3: Write Student Records (Roll, Name, Marks)
import pickle
def write_students:
with open("students.dat", "wb") as f:
n = int(input("How many students? "))
for i in range(n):
print(f"\nStudent {i+1}:")
roll = int(input(" Roll No: "))
name = input(" Name: ")
marks = float(input(" Marks: "))
record = {"roll": roll, "name": name, "marks": marks}
pickle.dump(record, f)
print("\nAll records written successfully!")
write_students
# Test Run:
# How many students? 3
#
# Student 1:
# Roll No: 101
# Name: Aman
# Marks: 85.5
#
# Student 2:
# Roll No: 102
# Name: Priya
# Marks: 92.0
#
# Student 3:
# Roll No: 103
# Name: Rahul
# Marks: 78.5
#
# All records written successfully!
Program 4: Search by Roll Number
import pickle
def search_student:
roll_search = int(input("Enter roll number to search: "))
found = False
with open("students.dat", "rb") as f:
try:
while True:
record = pickle.load(f)
if record["roll"] == roll_search:
print("\nStudent Found!")
print(f" Roll No : {record['roll']}")
print(f" Name : {record['name']}")
print(f" Marks : {record['marks']}")
found = True
break
except EOFError:
pass
if not found:
print(f"Student with Roll No {roll_search} not found.")
search_student
# Test Run 1:
# Enter roll number to search: 102
# Student Found!
# Roll No : 102
# Name : Priya
# Marks : 92.0
# Test Run 2:
# Enter roll number to search: 999
# Student with Roll No 999 not found.
Program 5: Update Marks for a Roll Number
import pickle
def update_marks:
roll_update = int(input("Enter roll number to update: "))
new_marks = float(input("Enter new marks: "))
found = False
# Read all records
records = []
with open("students.dat", "rb") as f:
try:
while True:
record = pickle.load(f)
if record["roll"] == roll_update:
print(f"Old marks: {record['marks']}")
record["marks"] = new_marks
print(f"New marks: {record['marks']}")
found = True
records.append(record)
except EOFError:
pass
if found:
# Write all records back
with open("students.dat", "wb") as f:
for record in records:
pickle.dump(record, f)
print("Record updated successfully!")
else:
print(f"Student with Roll No {roll_update} not found.")
update_marks
# Test Run:
# Enter roll number to update: 103
# Enter new marks: 88.0
# Old marks: 78.5
# New marks: 88.0
# Record updated successfully!
Program 6: Delete a Record
import pickle
def delete_student:
roll_delete = int(input("Enter roll number to delete: "))
found = False
# Read all records
records = []
with open("students.dat", "rb") as f:
try:
while True:
record = pickle.load(f)
if record["roll"] == roll_delete:
print(f"Deleting: {record['name']} (Roll: {record['roll']})")
found = True
else:
records.append(record)
except EOFError:
pass
if found:
# Write remaining records back
with open("students.dat", "wb") as f:
for record in records:
pickle.dump(record, f)
print("Record deleted successfully!")
else:
print(f"Student with Roll No {roll_delete} not found.")
delete_student
# Test Run:
# Enter roll number to delete: 102
# Deleting: Priya (Roll: 102)
# Record deleted successfully!
Program 7: Display All Records
import pickle
def display_all:
print("\n" + "=" * 40)
print(f"{'Roll':<8}{'Name':<15}{'Marks':<10}")
print("=" * 40)
count = 0
with open("students.dat", "rb") as f:
try:
while True:
record = pickle.load(f)
print(f"{record['roll']:<8}{record['name']:<15}{record['marks']:<10}")
count += 1
except EOFError:
pass
print("=" * 40)
print(f"Total records: {count}")
display_all
# Output:
# ========================================
# Roll Name Marks
# ========================================
# 101 Aman 85.5
# 102 Priya 92.0
# 103 Rahul 78.5
# ========================================
# Total records: 3
Program 8: Employee Management System (Complete CRUD)
import pickle
import os
FILENAME = "employees.dat"
def add_employee:
"""Add a new employee record."""
with open(FILENAME, "ab") as f:
empid = int(input("Enter Employee ID: "))
name = input("Enter Name: ")
dept = input("Enter Department: ")
salary = float(input("Enter Salary: "))
record = {"empid": empid, "name": name, "dept": dept, "salary": salary}
pickle.dump(record, f)
print("Employee added successfully!\n")
def display_all:
"""Display all employee records."""
if not os.path.exists(FILENAME):
print("No records found.\n")
return
print("\n" + "=" * 55)
print(f"{'ID':<8}{'Name':<15}{'Dept':<12}{'Salary':<12}")
print("=" * 55)
count = 0
with open(FILENAME, "rb") as f:
try:
while True:
rec = pickle.load(f)
print(f"{rec['empid']:<8}{rec['name']:<15}{rec['dept']:<12}{rec['salary']:<12.2f}")
count += 1
except EOFError:
pass
print("=" * 55)
print(f"Total employees: {count}\n")
def search_employee:
"""Search for an employee by ID."""
empid = int(input("Enter Employee ID to search: "))
found = False
with open(FILENAME, "rb") as f:
try:
while True:
rec = pickle.load(f)
if rec["empid"] == empid:
print(f"\nEmployee Found:")
print(f" ID : {rec['empid']}")
print(f" Name : {rec['name']}")
print(f" Department : {rec['dept']}")
print(f" Salary : {rec['salary']:.2f}")
found = True
break
except EOFError:
pass
if not found:
print(f"Employee ID {empid} not found.\n")
def update_employee:
"""Update salary of an employee."""
empid = int(input("Enter Employee ID to update: "))
found = False
records = []
with open(FILENAME, "rb") as f:
try:
while True:
rec = pickle.load(f)
if rec["empid"] == empid:
print(f"Current salary: {rec['salary']:.2f}")
rec["salary"] = float(input("Enter new salary: "))
found = True
records.append(rec)
except EOFError:
pass
if found:
with open(FILENAME, "wb") as f:
for rec in records:
pickle.dump(rec, f)
print("Salary updated successfully!\n")
else:
print(f"Employee ID {empid} not found.\n")
def delete_employee:
"""Delete an employee record."""
empid = int(input("Enter Employee ID to delete: "))
found = False
records = []
with open(FILENAME, "rb") as f:
try:
while True:
rec = pickle.load(f)
if rec["empid"] == empid:
print(f"Deleting: {rec['name']} (ID: {rec['empid']})")
found = True
else:
records.append(rec)
except EOFError:
pass
if found:
with open(FILENAME, "wb") as f:
for rec in records:
pickle.dump(rec, f)
print("Record deleted successfully!\n")
else:
print(f"Employee ID {empid} not found.\n")
# Main menu
def main:
while True:
print("=" * 35)
print(" EMPLOYEE MANAGEMENT SYSTEM")
print("=" * 35)
print(" 1. Add Employee")
print(" 2. Display All Employees")
print(" 3. Search Employee")
print(" 4. Update Salary")
print(" 5. Delete Employee")
print(" 6. Exit")
print("=" * 35)
choice = input("Enter your choice (1-6): ")
if choice == "1":
add_employee
elif choice == "2":
display_all
elif choice == "3":
search_employee
elif choice == "4":
update_employee
elif choice == "5":
delete_employee
elif choice == "6":
print("Thank you! Goodbye.")
break
else:
print("Invalid choice. Try again.\n")
main
# Sample Interaction:
# ===================================
# EMPLOYEE MANAGEMENT SYSTEM
# ===================================
# 1. Add Employee
# 2. Display All Employees
# 3. Search Employee
# 4. Update Salary
# 5. Delete Employee
# 6. Exit
# ===================================
# Enter your choice (1-6): 1
# Enter Employee ID: 1001
# Enter Name: Anita
# Enter Department: IT
# Enter Salary: 55000
# Employee added successfully!
Common Mistakes
| Mistake | Correct Approach |
|---|---|
Opening binary file without "b" in mode |
Always use "rb", "wb", "ab" for pickle |
Not handling EOFError when reading |
Always wrap pickle.load in try-except EOFError |
Using read / write with binary files |
Use pickle.load and pickle.dump |
Forgetting import pickle |
Must import before using dump or load |
Appending with "wb" instead of "ab" |
"wb" overwrites the file; use "ab" to append |
| Trying to update/delete in-place | Read all records, modify in memory, write all back |
$1$2 Quick Tips
- Always import pickle at the top, forgetting this is a common mark-losing error.
- EOFError handling is the most tested concept. The
try-while-True-except EOFErrorpattern appears in almost every binary file question. - dump writes, load reads - do not confuse with text file methods.
- Update and Delete follow the same pattern: read all into a list, modify the list, write all back.
- Know the difference between
"wb"(overwrites) and"ab"(appends). - Pickling vs Unpickling definition is a 1-2 mark theory question.
- Records are usually stored as dictionaries - practice the
{"key": value}pattern. - Binary files cannot be opened in a text editor, this is a common True/False question.
Prefer watching over reading?
Subscribe for free.