Binary File Operations in Python

Binary File Operations in Python

1. Introduction to Binary Files

A Binary File stores data in the same format (0s and 1s) as it is held in the computer’s primary memory (RAM).

  • No Delimiters: Unlike text files, binary files do not contain end-of-line (\n) delimiters.
  • Non-Human Readable: Opening a binary file in a standard text editor (like Notepad) displays unreadable raw byte sequences or gibberish characters.
  • Examples: .dat files, image files (.jpg, .png), compiled code (.pyc), audio, and video files.

2. Need for Binary Files over Text Files

While text files are human-readable, binary files are used in programming due to key advantages:

  1. No Translation Overhead: Text files require encoding/decoding (converting binary in memory to ASCII/Unicode text on disk). Binary files store data directly as machine-readable bytes, making read/write operations faster.
  2. Preservation of Data Structure: Python complex structures (lists, dictionaries, tuples, custom objects) can be written directly to a binary file without manual string conversion.
  3. Storage Efficiency: Numbers (e.g., large floats or integers) take less disk space in binary format compared to their string representations in text files.
  4. Security/Privacy: Data is not directly readable by unauthorized users inspecting the file via plain text editors.

3. Text File vs. Binary File

ParameterText FileBinary File
Data RepresentationCharacters encoded in ASCII or Unicode.Raw bytes (0s and 1s) matching memory layout.
EOL DelimiterEnds lines with special character \n.No line delimiters; records are processed as byte streams.
PerformanceSlower due to encoding/decoding conversions.Faster due to direct binary transfer.
ReadabilityHuman readable using standard text editors.Non-readable in text editors.
File Extension.txt, .csv, .py.dat, .bin, .exe, .jpg

4. Basic Operations on a Binary File

A. Opening a Binary File

Binary files are opened using Python’s built-in open() function by specifying a binary mode (mode containing 'b').

file_object = open("filename.dat", "mode")

File Opening Modes:

ModeDescriptionFile Pointer PositionBehavior if File Doesn’t Exist
rbRead-only in binary mode.Beginning of fileRaises FileNotFoundError.
rb+Read and Write in binary mode.Beginning of fileRaises FileNotFoundError.
wbWrite-only in binary mode (truncates existing content).Beginning of fileCreates a new file.
wb+Write and Read in binary mode (truncates existing content).Beginning of fileCreates a new file.
abAppend-only in binary mode.End of fileCreates a new file.
ab+Append and Read in binary mode.End of fileCreates a new file.

B. Closing a Binary File

Closing a file flushes any unwritten buffers to disk and frees system resources.

f = open("data.dat", "rb")
# Perform operations
f.close()

5. The pickle Module

Python’s pickle module is used to convert Python object structures into byte streams and vice versa.

  • Pickling (Serialization): Converting a Python object (List, Dictionary, etc.) into a stream of bytes to store it in a binary file.
  • Unpickling (Deserialization): Converting a stream of bytes from a binary file back into the original Python object.

Syntax to Import:

import pickle

Core Methods:

  1. pickle.dump(object, file_handle)
    • Writes the pickled (serialized) representation of object to the open binary file file_handle.
  2. pickle.load(file_handle)
    • Reads the pickled representation from the open binary file file_handle and reconstructs the original Python object.
    • Raises EOFError (End Of File Error) when reaching the end of the file.

6. Code Implementation of Binary File Operations

A. Write / Create Operation (pickle.dump)

Writing records (e.g., student dictionaries) to a binary file.

import pickle

def create_file():
    file = open("students.dat", "wb")
    students = [
        {"roll": 101, "name": "Aman", "marks": 85.5},
        {"roll": 102, "name": "Priya", "marks": 92.0},
        {"roll": 103, "name": "Rohan", "marks": 78.0}
    ]
    
    for student in students:
        pickle.dump(student, file)
        
    print("Data written successfully.")
    file.close()

create_file()

B. Read Operation (pickle.load)

Reading records using a try-except block to handle EOFError when all records are loaded.

import pickle

def read_file():
    try:
        file = open("students.dat", "rb")
        while True:
            record = pickle.load(file)
            print(record)
    except EOFError:
        file.close()
    except FileNotFoundError:
        print("File does not exist.")

read_file()

C. Search Operation

Searching for a specific record based on a condition (e.g., searching by roll number).

import pickle

def search_record(roll_no):
    found = False
    try:
        file = open("students.dat", "rb")
        while True:
            record = pickle.load(file)
            if record["roll"] == roll_no:
                print("Record Found:", record)
                found = True
                break
    except EOFError:
        file.close()
        
    if not found:
        print(f"Record with Roll No {roll_no} not found.")

search_record(102)

D. Append Operation (ab mode)

Adding new records to an existing binary file without altering previous data.

import pickle

def append_record():
    file = open("students.dat", "ab")
    new_student = {"roll": 104, "name": "Sneha", "marks": 88.5}
    
    pickle.dump(new_student, file)
    print("New record appended successfully.")
    file.close()

append_record()

E. Update Operation

There are two standard methods we can use for updating in binary files:

Method 1: The Temporary List Approach (Most Standard & Safe)

Read all records into a Python list, update the dictionary in memory, and then write the updated list back to the binary file.

import pickle

updated_roll = 2
new_name = "Priya Sharma"
found = False

# Step 1: Read all records into a list
records = []
try:
    with open("students.dat", "rb") as file:
        while True:
            student = pickle.load(file)
            if student["roll"] == updated_roll:
                student["name"] = new_name
                found = True
            records.append(student)
except EOFError:
    pass

# Step 2: Overwrite the file with updated data
if found:
    with open("students.dat", "wb") as file:
        for student in records:
            pickle.dump(student, file)
    print("Record updated successfully!")
else:
    print("Record not found.")

Method 2: The In-Place (rb+) Method

Updating an existing record (e.g., modifying marks for a given roll number) using file pointer navigation (seek() and tell()) or temporary files.

import pickle

def update_marks(roll_no, new_marks):
    updated = False
    try:
        file = open("students.dat", "rb+")
        while True:
            pos = file.tell()  # Save initial position of the record
            record = pickle.load(file)
            
            if record["roll"] == roll_no:
                record["marks"] = new_marks
                file.seek(pos)  # Move back to start of record
                pickle.dump(record, file)
                print(f"Record for Roll No {roll_no} updated successfully.")
                updated = True
                break
    except EOFError:
        file.close()
        
    if not updated:
        print("Record not found to update.")

update_marks(103, 84.0)

Key Points for Examinations

  • Remember that binary mode requires passing binary strings or using the pickle library for Python structures.
  • Always handle EOFError when reading binary files sequentially in a while True loop.
  • tell() returns the current byte position of the file pointer.
  • seek(offset, whence) moves the file pointer to a specified byte position.

CSV File Handling in Python

A CSV (Comma Separated Values) file is a text file where tabular data (rows and columns) is stored with fields separated by a delimiter, usually a comma.

1. Importing the csv Module

Python provides a built-in module called csv to handle reading and writing operations on CSV files.

import csv

2. Opening and Closing CSV Files

Opening a CSV File

Use Python’s built-in open() function. Always specify newline='' when working with CSV files to prevent blank lines between rows across different operating systems.

# Open for writing
file_obj = open('data.csv', 'w', newline='')

# Open for reading
file_obj = open('data.csv', 'r', newline='')

Closing a CSV File

  • Explicit method:file_obj.close()
  • Recommended method (with statement): Automatically handles file closing even if an error occurs.
with open('data.csv', 'r', newline='') as file_obj:
    # Operations are performed here
    pass
# File closes automatically outside the block

3. Writing into a CSV File

To write data into a CSV file, first create a writer object using csv.writer().

Writer Methods

MethodSyntaxDescription
csv.writer()csv.writer(file_object)Creates and returns a writer object to write delimited rows.
writerow()writer_obj.writerow(sequence)Writes a single row (a 1D list/tuple) into the file.
writerows()writer_obj.writerows(nested_sequence)Writes multiple rows (a 2D list of lists/tuples) at once.

Complete Writing Example of csv file:

import csv

# Sample data
header = ['RollNo', 'Name', 'Marks']
single_student = [101, 'Ananya', 95]
multiple_students = [
    [102, 'Rohan', 88],
    [103, 'Priya', 92],
    [104, 'Kabir', 79]
]

with open('students.csv', 'w', newline='') as file:
    csv_writer = csv.writer(file)
    
    # Write header
    csv_writer.writerow(header)
    
    # Write one record
    csv_writer.writerow(single_student)
    
    # Write multiple records at once
    csv_writer.writerows(multiple_students)

print("Data written successfully!")

4. Reading from a CSV File

To read data, create a reader object using csv.reader().

Reader Method

  • csv.reader(file_object): Returns an iterable reader object. Iterating over it yields each row as a list of strings.

Complete Reading Example

import csv

with open('students.csv', 'r', newline='') as file:
    csv_reader = csv.reader(file)
    
    # Iterate through each row in the CSV
    for row in csv_reader:
        print(row)

Output:

['RollNo', 'Name', 'Marks']
['101', 'Ananya', '95']
['102', 'Rohan', '88']
['103', 'Priya', '92']
['104', 'Kabir', '79']

Key Exam Points to Remember

  1. newline='' Parameter: Omitting newline='' while opening a file in write mode generates extra blank lines between rows on Windows platforms.
  2. Data Types: All elements retrieved using csv.reader() are returned as strings. Convert them explicitly (e.g., int(row[2])) when performing numerical operations.
  3. writerow() vs writerows():
    • writerow([1, 'A', 90]) writes 1 line.
    • writerows([[1, 'A', 90], [2, 'B', 85]]) writes multiple lines.
  4. Custom Delimiters: The default delimiter is ,. For other delimiters (like ; or \t), pass the delimiter argument:Pythoncsv_writer = csv.writer(file, delimiter='\t')

Questions on CSV file:

Q1: Suman is an intern at a software startup. The company has assigned her a task to create a CSV file named CLUB. CSV, to store the records of the Club members. After discussing with Club Incharge, Suman has planned to store the following content of members in the file CLUB.CSV:
[Mno, Name, Mobile, Fee]
Where
Mno – Member Number
Name -Name of the Member
Mobile- Member’s Mobile Number
Fee- Fee amount
Assuming you are asked to help Suman in her assignment, write a Python code for performing the following tasks with the help of user-defined functions:
NewMembers(): to accept records of members from the user and add them to the file CLUB.CSV.
PriorityMember() to find and display those members from the file CLUB. CSV, who are paying Fee more than 35000.

import csv

# Function 1: To accept member records from user and add to CLUB.CSV
def NewMembers():
    with open('CLUB.CSV', 'a', newline='') as file:
        writer = csv.writer(file)
        
        while True:
            mno = input("Enter Member Number: ")
            name = input("Enter Member Name: ")
            mobile = input("Enter Mobile Number: ")
            fee = float(input("Enter Fee: "))
            
            # Write record to CSV file
            writer.writerow([mno, name, mobile, fee])
            
            ch = input("Do you want to add more records? (Y/N): ")
            if ch.lower() != 'y':
                break
                
    print("Record(s) added successfully!\n")


# Function 2: To display members whose Fee is more than 35000
def PriorityMember():
    try:
        with open('CLUB.CSV', 'r', newline='') as file:
            reader = csv.reader(file)
            
            found = False
            print("\n--- Priority Members (Fee > 35000) ---")
            
            for row in reader:
                # Check if row is not empty and fee > 35000
                if row and float(row[3]) > 35000:
                    print(f"Mno: {row[0]} | Name: {row[1]} | Mobile: {row[2]} | Fee: {row[3]}")
                    found = True
                    
            if not found:
                print("No member found with Fee greater than 35000.")
                
    except FileNotFoundError:
        print("CLUB.CSV file does not exist.")

All binary file operations (write,read,search,edit,delete) in Python

import pickle
def write():
    #writing data on a binary file
    with open("students.dat","wb") as fh:
        records=[
              {"name":"Shorya", "class":12, "roll":1, "marks":[60,14,33]},
              {"name":"Shivam", "class":12, "roll":2, "marks":[60,14,33]},
              {"name":"Tanuj", "class":12, "roll":3, "marks":[60,14,33]},
              {"name":"Ritika", "class":12, "roll":4, "marks":[60,14,33]}
             ]
        for record in records:
            pickle.dump(record,fh)        
    print("record saved.")

def search():
    # searching data from binary file
    with open("students.dat","rb") as fh:
        rl=int(input("enter roll to search:"))
        found=False
        while True:
            try:
                data=pickle.load(fh)
                if data.get("roll")==rl:
                    print(data)
                    found=True
                    break
            except EOFError:
                break
        if found==False:
            print("not found")
def read():
    # reading data from binary file
    with open("students.dat","rb") as fh:
        while True:
            try:
                data=pickle.load(fh)
                print(data)
            except EOFError:
                break
def update():
    # update data from binary file
    uroll=int(input("Enter roll no to edit:"))
    records=[]
    found=False
    with open("students.dat","rb") as fh:
        while True:
            try:
                data=pickle.load(fh)
                if data["roll"]==uroll:
                    found=True
                    print(data)
                    data["name"]=input("Enter new name")
                records.append(data)
            except EOFError:
                break
    #writing updated data on a binary file
    with open("students.dat","wb") as fh:
        for record in records:
            pickle.dump(record,fh)
    if found:
        print("Record updated.")
    else:
        print("No record found.")
def delete():
    # delete data from binary file
    uroll=int(input("Enter roll no to delete:"))
    records=[]
    found=False
    with open("students.dat","rb") as fh:
        while True:
            try:
                data=pickle.load(fh)
                if data["roll"]==uroll:
                    found=True
                    print(data)
                    continue                    
                records.append(data)
            except EOFError:
                break
    #writing updated data on a binary file
    with open("students.dat","wb") as fh:
        for record in records:
            pickle.dump(record,fh)
    if found:
        print("Record deleted")
    else:
        print("No record found.")

Multiple Choice Questions (MCQs) on Binary File Handling

Q1. Which Python module is mandatory to import for performing serialization and deserialization operations on binary files?

(a) sys

(b) pickle

(c) struct

(d) os

Q2. Which exception is raised when Python reaches the end of a binary file while reading records using pickle.load()?

(a) IOError

(b) FileNotFoundError

(c) EOFError

(d) ValueError

Q3. What is the correct file opening mode to append data to an existing binary file without overwriting its existing content?

(a) 'a'

(b) 'wb'

(c) 'ab'

(d) 'rb+'

Q4. What is the purpose of the pickle.dump() function?

(a) To read Python objects from a binary file.

(b) To write pickled Python objects to a binary file.

(c) To clear all data inside a binary file.

(d) To return the current byte position of the file pointer.

Q5. Which function returns the current byte position of the file pointer inside an open file?

(a) seek()

(b) tell()

(c) read()

(d) locate()

Q6. What will happen if you attempt to open a non-existent file in 'rb' mode?

(a) A new empty file will be created.

(b) The file will open in write mode automatically.

(c) Python raises a FileNotFoundError.

(d) Python raises an EOFError.

Q7. Which statement correctly describes the difference between text files and binary files?

(a) Text files store data in binary format; binary files store ASCII values.

(b) Text files use end-of-line (\n) delimiters; binary files do not use delimiters.

(c) Binary files require human-readable characters; text files store unformatted bytes.

(d) Reading binary files is slower than reading text files due to character encoding.

Q8. What is the role of file.seek(0, 0) in binary file handling?

(a) Moves the file pointer to the end of the file.

(b) Deletes the first record of the file.

(c) Moves the file pointer to the beginning of the file.

(d) Moves the file pointer 0 bytes forward from its current position.

Q9. Which argument order is required by the pickle.dump() function?

(a) pickle.dump(file_handle, object)

(b) pickle.dump(object, file_handle)

(c) pickle.dump(filename, object)

(d) pickle.dump(object, filename)

Q10. What mode should be used if you want to open a binary file for both reading and updating without clearing its existing content?

(a) 'wb+'

(b) 'rb+'

(c) 'ab'

(d) 'r+'

Assertion & Reason Questions

Directions: For questions 11 to 15, choose the correct option from the following:

  • (a) Both Assertion (A) and Reason (R) are true, and Reason (R) is the correct explanation of Assertion (A).
  • (b) Both Assertion (A) and Reason (R) are true, but Reason (R) is NOT the correct explanation of Assertion (A).
  • (c) Assertion (A) is true, but Reason (R) is false.
  • (d) Assertion (A) is false, but Reason (R) is true.

Q11.

  • Assertion (A): Binary files are faster to read and write compared to text files.
  • Reason (R): No translation or encoding/decoding takes place when reading/writing binary files.

Q12.

  • Assertion (A): The statement data = pickle.load(file_object) writes data to a binary file.
  • Reason (R): The pickle.load() function is used for deserialization (converting byte streams back into Python objects).

Q13.

  • Assertion (A): In Python binary file operations, opening a file in 'wb' mode overwrites all existing data if the file already exists.
  • Reason (R): The 'wb' mode truncates existing file contents upon opening or creates a new file if it doesn’t exist.

Q14.

  • Assertion (A): A while True loop used to read binary file records sequentially will loop infinitely unless stopped manually.
  • Reason (R): When pickle.load() reaches the end of a binary file, it automatically returns None.

Q15.

  • Assertion (A): The tell() function can be used to track the exact byte offset where a record starts before updating it in a binary file.
  • Reason (R): The seek() function allows repositioning the file pointer to a specific byte location for reading or writing.

Answer Key

MCQs

  1. (b) pickle
  2. (c) EOFError
  3. (c) 'ab'
  4. (b) To write pickled Python objects to a binary file.
  5. (b) tell()
  6. (c) Python raises a FileNotFoundError.
  7. (b) Text files use end-of-line (\n) delimiters; binary files do not use delimiters.
  8. (c) Moves the file pointer to the beginning of the file.
  9. (b) pickle.dump(object, file_handle)
  10. (b) 'rb+'

Assertion & Reason

  1. (a) Both (A) and (R) are true, and (R) is the correct explanation of (A).
  2. (d) Assertion (A) is false (it reads data, not writes), but Reason (R) is true.
  3. (a) Both (A) and (R) are true, and (R) is the correct explanation of (A).
  4. (c) Assertion (A) is true (without exception handling), but Reason (R) is false (pickle.load() raises EOFError, it doesn’t return None).
  5. (b) Both (A) and (R) are true, but (R) describes seek(), which is a complementary function rather than the direct explanation of how tell() works.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top