📓 Python Programming - File Handling


1. Text File Operations

Python provides easy ways to handle files for reading and writing.

Common File Modes: - 'r' → Read (default)

  • 'w' → Write (overwrites existing file or creates new)

  • 'a' → Append (adds to existing file)

  • 'rb' / 'wb' → Read/Write binary files

➤ Reading a Text File:

# Writing sample content for demonstration
with open("../files/sample.txt", "w") as file:
    file.write("Hello, this is a text file.\nSecond line of text.")

# Reading file
with open("../files/sample.txt", "r") as file:
    content = file.read()
    print(content)

➤ Writing to a Text File:

with open("../files/output.txt", "w") as file:
    file.write("This is a new file.\nFile handling in Python is easy!")

➤ Reading Files Line by Line:

# Method 1: Using readlines()
with open("../files/sample.txt", "r") as file:
    lines = file.readlines()
    for i, line in enumerate(lines, 1):
        print(f"Line {i}: {line.strip()}")

print("\n" + "="*30 + "\n")

# Method 2: Using for loop (memory efficient)
with open("../files/sample.txt", "r") as file:
    for line_num, line in enumerate(file, 1):
        print(f"Line {line_num}: {line.strip()}")

print("\n" + "="*30 + "\n")

# Method 3: Using readline() - one line at a time
with open("../files/sample.txt", "r") as file:
    line = file.readline()
    while line:
        print(f"Read: {line.strip()}")
        line = file.readline()

➤ Error Handling in File Operations:

# Handling FileNotFoundError
try:
    with open("../files/nonexistent.txt", "r") as file:
        content = file.read()
        print(content)
except FileNotFoundError:
    print("Error: File not found!")
except PermissionError:
    print("Error: Permission denied!")
except Exception as e:
    print(f"Unexpected error: {e}")

# Safe file writing with error handling
def safe_write_file(filename, content):
    try:
        with open(filename, "w") as file:
            file.write(content)
        print(f"Successfully wrote to {filename}")
    except PermissionError:
        print(f"Error: No permission to write to {filename}")
    except Exception as e:
        print(f"Error writing file: {e}")

# Test the function
safe_write_file("../files/test_write.txt", "Hello, World!")

# Safe file reading function
def safe_read_file(filename):
    try:
        with open(filename, "r") as file:
            return file.read()
    except FileNotFoundError:
        return f"Error: File '{filename}' not found"
    except PermissionError:
        return f"Error: No permission to read '{filename}'"
    except Exception as e:
        return f"Error reading file: {e}"

# Test the function
content = safe_read_file("../files/test_write.txt")
print(content)

2. File Path Handling with os Module

The os module helps work with file paths in a platform-independent way.

import os

# Current working directory
print("Current Directory:", os.getcwd())

# Create a file path
file_path = os.path.join(os.getcwd(), "output.txt")
print("File Path:", file_path)

➤ Checking File Existence & Operations:

# Check if file exists
if os.path.exists("../files/sample.txt"):
    print("File exists!")
else:
    print("File does not exist.")

# Get file size
if os.path.exists("../files/sample.txt"):
    file_size = os.path.getsize("../files/sample.txt")
    print(f"File size: {file_size} bytes")

# List files in directory
files = os.listdir("../files/")
print("Files in directory:", files)

# Create directory if it doesn't exist
if not os.path.exists("../files/new_folder"):
    os.makedirs("../files/new_folder")
    print("Directory created!")
else:
    print("Directory already exists!")

3. Working with CSV Files

CSV (Comma-Separated Values): - Simple format for storing tabular data.

  • Python provides the csv module to work with CSV files.

➤ Reading a CSV File:

import csv

# Creating a sample CSV file
with open("../files/data.csv", "w", newline="") as file:
    writer = csv.writer(file)
    writer.writerow(["Name", "Age"])
    writer.writerow(["Alice", 23])
    writer.writerow(["Bob", 28])

# Reading the CSV file
with open("../files/data.csv", "r") as file:
    reader = csv.reader(file)
    for row in reader:
        print(row)

➤ Using Dictionaries in CSV Files:

# Writing using DictWriter
with open("../files/data_dict.csv", "w", newline="") as file:
    fieldnames = ["Name", "Age"]
    writer = csv.DictWriter(file, fieldnames=fieldnames)
    writer.writeheader()
    writer.writerow({"Name": "Charlie", "Age": 30})
    writer.writerow({"Name": "Dana", "Age": 26})

# Reading using DictReader
with open("../files/data_dict.csv", "r") as file:
    reader = csv.DictReader(file)
    for row in reader:
        print(row)

4. Working with JSON

JSON (JavaScript Object Notation): - Popular data format for exchanging data.

  • Similar to Python dictionaries.

➤ Reading & Writing JSON:

import json

# Python dictionary
person = {"name": "Eve", "age": 29, "skills": ["Python", "Data Science"]}

# Writing to JSON file
with open("../files/person.json", "w") as file:
    json.dump(person, file)

# Reading JSON file
with open("../files/person.json", "r") as file:
    data = json.load(file)
    print(data)

➤ Parsing JSON Strings:

# JSON string
json_str = '{"name": "Frank", "age": 32}'

# Converting JSON string to dictionary
person = json.loads(json_str)
print(person["name"])

5. Binary File Handling

Binary files store data in binary format (images, videos, executables, etc.)

➤ Reading & Writing Binary Files:

# Write binary data
binary_data = b"Hello, this is binary data!\x00\x01\x02"

with open("../files/binary_file.bin", "wb") as file:
    file.write(binary_data)

# Read binary data
with open("../files/binary_file.bin", "rb") as file:
    data = file.read()
    print(f"Binary data: {data}")
    print(f"Data type: {type(data)}")

# Copy a file using binary mode (useful for images, videos, etc.)
def copy_file(source, destination):
    try:
        with open(source, "rb") as src:
            with open(destination, "wb") as dst:
                dst.write(src.read())
        print(f"File copied from {source} to {destination}")
    except FileNotFoundError:
        print(f"Source file {source} not found")
    except Exception as e:
        print(f"Error copying file: {e}")

# Create a test file and copy it
with open("../files/test_source.txt", "w") as file:
    file.write("This is a test file to copy.")

copy_file("../files/test_source.txt", "../files/test_copy.txt")

6. Modern File Handling with pathlib

pathlib is a modern, object-oriented way to handle file paths (Python 3.4+)

➤ Using pathlib for File Operations:

from pathlib import Path

# Create Path objects
current_dir = Path.cwd()
print(f"Current directory: {current_dir}")

# Create file path
file_path = Path("../files/pathlib_test.txt")
print(f"File path: {file_path}")

# Check if file exists
print(f"File exists: {file_path.exists()}")

# Create parent directories if they don't exist
file_path.parent.mkdir(parents=True, exist_ok=True)

# Write to file using pathlib
file_path.write_text("Hello from pathlib!")

# Read from file using pathlib
content = file_path.read_text()
print(f"File content: {content}")

# Get file information
if file_path.exists():
    print(f"File size: {file_path.stat().st_size} bytes")
    print(f"File name: {file_path.name}")
    print(f"File extension: {file_path.suffix}")
    print(f"Parent directory: {file_path.parent}")

# List files in directory
files_dir = Path("../files")
if files_dir.exists():
    print("\nFiles in directory:")
    for file in files_dir.iterdir():
        if file.is_file():
            print(f"  📄 {file.name}")
        elif file.is_dir():
            print(f"  📁 {file.name}/")

# Find files by pattern
print("\nText files:")
for txt_file in files_dir.glob("*.txt"):
    print(f"  📄 {txt_file.name}")

# Working with different path parts
sample_path = Path("/home/user/documents/file.txt")
print(f"\nPath parts:")
print(f"  Root: {sample_path.root}")
print(f"  Parts: {sample_path.parts}")
print(f"  Parent: {sample_path.parent}")
print(f"  Name: {sample_path.name}")
print(f"  Stem: {sample_path.stem}")
print(f"  Suffix: {sample_path.suffix}")

7. Practical File Handling Examples

➤ Log File Processing:

# Create a sample log file
log_content = """2024-01-15 10:30:25 INFO User logged in
2024-01-15 10:31:15 ERROR Failed to connect to database
2024-01-15 10:32:45 INFO Database connection restored
2024-01-15 10:33:20 WARNING High memory usage detected
2024-01-15 10:34:10 INFO User logged out"""

with open("../files/app.log", "w") as file:
    file.write(log_content)

# Process log file
def analyze_log_file(filename):
    log_stats = {"INFO": 0, "ERROR": 0, "WARNING": 0}

    try:
        with open(filename, "r") as file:
            for line in file:
                if "INFO" in line:
                    log_stats["INFO"] += 1
                elif "ERROR" in line:
                    log_stats["ERROR"] += 1
                elif "WARNING" in line:
                    log_stats["WARNING"] += 1

        return log_stats
    except FileNotFoundError:
        return "Log file not found"

# Analyze the log
stats = analyze_log_file("../files/app.log")
print("Log Analysis:")
for level, count in stats.items():
    print(f"  {level}: {count} messages")

# Filter errors from log
def extract_errors(log_file, error_file):
    try:
        with open(log_file, "r") as infile, open(error_file, "w") as outfile:
            for line in infile:
                if "ERROR" in line:
                    outfile.write(line)
        print(f"Errors extracted to {error_file}")
    except FileNotFoundError:
        print(f"Log file {log_file} not found")

extract_errors("../files/app.log", "../files/errors.log")

➤ Configuration File Handling:

# Create a configuration file
config = {
    "database": {
        "host": "localhost",
        "port": 5432,
        "username": "admin"
    },
    "app": {
        "name": "MyApp",
        "version": "1.0.0",
        "debug": True
    }
}

# Save configuration
with open("../files/config.json", "w") as file:
    json.dump(config, file, indent=2)

# Load and use configuration
def load_config(filename):
    try:
        with open(filename, "r") as file:
            return json.load(file)
    except FileNotFoundError:
        print(f"Config file {filename} not found")
        return None
    except json.JSONDecodeError:
        print(f"Invalid JSON in {filename}")
        return None

# Load configuration
app_config = load_config("../files/config.json")
if app_config:
    print(f"App Name: {app_config['app']['name']}")
    print(f"Database Host: {app_config['database']['host']}")
    print(f"Debug Mode: {app_config['app']['debug']}")

# Update configuration
def update_config(filename, section, key, value):
    config = load_config(filename)
    if config:
        config[section][key] = value
        with open(filename, "w") as file:
            json.dump(config, file, indent=2)
        print(f"Updated {section}.{key} = {value}")

# Update debug mode
update_config("../files/config.json", "app", "debug", False)

Example Prompt to ChatGPT: ``` "Generate Python code to read a JSON file containing student records and print their names."

🎯 Quick Recap

✅ File operations: reading, writing, appending, line-by-line processing

✅ Error handling: try-except blocks for robust file operations

✅ Use os module for file path handling and file system operations

✅ CSV files: csv.reader, csv.writer, and dictionaries

✅ JSON: Read, write, parse structured data

✅ Binary files: handling images, executables, and other binary data

✅ Modern pathlib: object-oriented file path handling

✅ Practical examples: log processing, configuration files

📝 Practice Exercises

Basic Level:

  1. Write a program to create a text file with your name and age.

  2. Read the file you just created and print its contents.

  3. Create a CSV file with three student records (name, age, grade).

  4. Read and print all names from the CSV file.

  5. Write a program to save a dictionary as a JSON file and read it back.

Intermediate Level:

  1. Write a program that reads a text file line by line and counts the number of lines.

  2. Create a program that handles FileNotFoundError when trying to read a non-existent file.

  3. Write a function that copies a file from one location to another using binary mode.

  4. Use pathlib to create a directory and list all .txt files in it.

  5. Create a log analyzer that counts different log levels (INFO, ERROR, WARNING).

Advanced Level:

  1. Write a program that reads a large file efficiently without loading it entirely into memory.

  2. Create a configuration manager that loads, updates, and saves JSON configuration files.

  3. Write a file backup system that creates timestamped backups of important files.

  4. Build a CSV data processor that filters and transforms data before saving.

  5. Create a file monitor that tracks changes in a directory and logs them.