intermediate Step 11 of 20

File Handling

Python Programming

File Handling

Working with files is a fundamental skill in programming. Whether you are reading configuration files, processing data from CSV files, writing logs, or saving application state, you need to know how to interact with the file system. Python makes file handling straightforward with its built-in open() function and context managers. Understanding file modes, encoding, and proper resource management ensures your programs handle files safely and efficiently.

Opening and Reading Files

# The best way: using 'with' statement (context manager)
# Automatically closes the file when the block exits
with open("example.txt", "r") as file:
    content = file.read()        # Read entire file as string
    print(content)

# Read line by line (memory efficient for large files)
with open("example.txt", "r") as file:
    for line in file:
        print(line.strip())      # strip() removes trailing newline

# Read all lines into a list
with open("example.txt", "r") as file:
    lines = file.readlines()     # List of strings
    print(f"Total lines: {len(lines)}")

# Read a specific number of characters
with open("example.txt", "r") as file:
    first_100 = file.read(100)   # First 100 characters
    next_100 = file.read(100)    # Next 100 characters

# Read single line
with open("example.txt", "r") as file:
    first_line = file.readline()
    second_line = file.readline()

Writing to Files

# Write mode ('w') — creates file or overwrites existing
with open("output.txt", "w") as file:
    file.write("Hello, World!\n")
    file.write("This is line 2.\n")

# Append mode ('a') — adds to end of file
with open("log.txt", "a") as file:
    file.write("New log entry\n")

# Write multiple lines
lines = ["Line 1\n", "Line 2\n", "Line 3\n"]
with open("output.txt", "w") as file:
    file.writelines(lines)

# Using print() to write to files
with open("output.txt", "w") as file:
    print("Hello, World!", file=file)
    print("No need for \\n", file=file)

# Write with specific encoding
with open("unicode.txt", "w", encoding="utf-8") as file:
    file.write("Hello 世界 🌍\n")

Working with CSV Files

import csv

# Writing CSV
data = [
    ["Name", "Age", "City"],
    ["Alice", 30, "New York"],
    ["Bob", 25, "Los Angeles"],
    ["Charlie", 35, "Chicago"]
]

with open("people.csv", "w", newline="") as file:
    writer = csv.writer(file)
    writer.writerows(data)

# Reading CSV
with open("people.csv", "r") as file:
    reader = csv.reader(file)
    header = next(reader)    # Skip header row
    for row in reader:
        name, age, city = row
        print(f"{name} is {age} years old from {city}")

# DictReader — access columns by name
with open("people.csv", "r") as file:
    reader = csv.DictReader(file)
    for row in reader:
        print(f"{row['Name']}: {row['City']}")

# DictWriter
with open("output.csv", "w", newline="") as file:
    fieldnames = ["name", "score"]
    writer = csv.DictWriter(file, fieldnames=fieldnames)
    writer.writeheader()
    writer.writerow({"name": "Alice", "score": 95})
    writer.writerow({"name": "Bob", "score": 87})

Working with JSON Files

import json

# Writing JSON
data = {
    "users": [
        {"name": "Alice", "age": 30, "active": True},
        {"name": "Bob", "age": 25, "active": False}
    ],
    "total": 2
}

with open("data.json", "w") as file:
    json.dump(data, file, indent=2)

# Reading JSON
with open("data.json", "r") as file:
    loaded = json.load(file)
    for user in loaded["users"]:
        status = "active" if user["active"] else "inactive"
        print(f"{user['name']} ({status})")

File System Operations

import os
from pathlib import Path

# Check if file exists
if os.path.exists("myfile.txt"):
    print("File exists")

# Using pathlib (modern approach)
path = Path("data/output.txt")
path.parent.mkdir(parents=True, exist_ok=True)  # Create directories
path.write_text("Hello from pathlib!")
content = path.read_text()

# List files in directory
for item in Path(".").iterdir():
    if item.is_file():
        print(f"File: {item.name} ({item.stat().st_size} bytes)")

# Find files by pattern
for py_file in Path(".").glob("**/*.py"):
    print(py_file)

# Copy, rename, delete
import shutil
shutil.copy("source.txt", "backup.txt")
os.rename("old_name.txt", "new_name.txt")
os.remove("temp.txt")  # Delete file
Pro tip: Always use the with statement (context manager) when working with files. It guarantees the file is properly closed even if an exception occurs, preventing resource leaks and data corruption.

Key Takeaways

  • Always use with open(...) as f: to ensure files are properly closed after use.
  • File modes: "r" (read), "w" (write/overwrite), "a" (append), "rb"/"wb" (binary).
  • Use the csv module for CSV files and json module for JSON files — do not parse them manually.
  • The pathlib.Path class provides a modern, object-oriented way to work with file paths and is preferred over os.path.
  • Specify encoding="utf-8" when working with text files that may contain non-ASCII characters.