Skip to content
beginner Phase 3 · Python Advanced

File I/O & Serialization

Read/write files, handle CSV, JSON, and pickle serialization.

1h
0 problems
Topic Progress 0%

Text File Operations

Opening Files

# File modes
# 'r' - Read (default)
# 'w' - Write (truncates file)
# 'a' - Append
# 'x' - Exclusive create (fails if exists)
# 'b' - Binary mode
# 't' - Text mode (default)
# '+' - Read and write

# Using context manager (recommended)
with open('data.txt', 'r') as f:
    content = f.read()

# Without context manager (not recommended)
f = open('data.txt', 'r')
try:
    content = f.read()
finally:
    f.close()

Reading Files

# Read entire file
with open('data.txt', 'r') as f:
    content = f.read()  # Returns string

# Read line by line
with open('data.txt', 'r') as f:
    line = f.readline()  # First line
    lines = f.readlines()  # Rest as list

# Iterating (memory efficient)
with open('data.txt', 'r') as f:
    for line in f:
        print(line.strip())  # Removes newline

Writing Files

# Write string
with open('output.txt', 'w') as f:
    f.write('Hello\n')
    f.write('World\n')

# Writelines (no newlines added)
with open('output.txt', 'w') as f:
    f.writelines(['Line 1\n', 'Line 2\n'])

# Append mode
with open('log.txt', 'a') as f:
    f.write('New entry\n')

# Print to file
with open('output.txt', 'w') as f:
    print('Hello', file=f)
    print('World', file=f)

File Information

import os

# File size
size = os.path.getsize('data.txt')

# Check if file exists
exists = os.path.exists('data.txt')

# File info
name = os.path.basename('/path/to/file.txt')  # 'file.txt'
dirname = os.path.dirname('/path/to/file.txt')  # '/path/to'
base, ext = os.path.splitext('file.txt')  # ('file', '.txt')

Large File Processing

# ✅ Memory efficient - processes line by line
def process_large_file(filename):
    with open(filename, 'r') as f:
        for line in f:  # Lazy iteration
            process(line)

# ❌ Loads entire file into memory
def process_large_file_bad(filename):
    with open(filename, 'r') as f:
        lines = f.readlines()  # All lines in memory!
        for line in lines:
            process(line)

Binary Files

Reading Binary Files

# Read entire binary file
with open('image.png', 'rb') as f:
    data = f.read()

# Read in chunks (memory efficient)
with open('large_video.mp4', 'rb') as f:
    while True:
        chunk = f.read(8192)  # 8KB chunks
        if not chunk:
            break
        process(chunk)

Writing Binary Files

# Write binary data
with open('output.bin', 'wb') as f:
    f.write(b'Hello, World!')

# Copy file
def copy_file(src, dst, chunk_size=8192):
    with open(src, 'rb') as src_file, open(dst, 'wb') as dst_file:
        while True:
            chunk = src_file.read(chunk_size)
            if not chunk:
                break
            dst_file.write(chunk)

Working with Bytes

# Bytes vs strings
text = 'Hello'      # str (Unicode)
data = b'Hello'     # bytes (ASCII/binary)

# Converting
encoded = 'Hello'.encode('utf-8')  # bytes
decoded = b'Hello'.decode('utf-8')  # str

# Bytes operations
chunk = b'Hello, World!'
chunk[0]         # 72 (ASCII for 'H')
chunk[0:5]       # b'Hello'
len(chunk)       # 13

Pickle for Python Objects

import pickle

# Save object to file
data = {'users': ['Alice', 'Bob'], 'count': 42}
with open('data.pkl', 'wb') as f:
    pickle.dump(data, f)

# Load object from file
with open('data.pkl', 'rb') as f:
    loaded = pickle.load(f)

print(loaded)  # {'users': ['Alice', 'Bob'], 'count': 42}

# ⚠️ Warning: Never unpickle untrusted data!
# Pickle can execute arbitrary code

JSON Files

import json

# Write JSON
with open('data.json', 'w') as f:
    json.dump({'name': 'Alice', 'age': 30}, f, indent=2)

# Read JSON
with open('data.json', 'r') as f:
    data = json.load(f)

print(data)  # {'name': 'Alice', 'age': 30}

CSV Files

import csv

# Write CSV
with open('data.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(['Name', 'Age'])
    writer.writerow(['Alice', 30])

# Read CSV
with open('data.csv', 'r') as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)  # ['Name', 'Age']

Modern File Operations with pathlib

pathlib Basics

from pathlib import Path

# Create Path object
p = Path('.')
home = Path.home()
current = Path.cwd()

# Path operations
file_path = Path('data') / 'users' / 'alice.txt'
print(file_path)  # data/users/alice.txt

# Get parts
p = Path('/home/user/file.txt'
print(p.name)      # 'file.txt'
print(p.stem)      # 'file'
print(p.suffix)    # '.txt'
print(p.parent)    # Path('/home/user')
print(p.parts)     # ('/', 'home', 'user', 'file.txt')

File Operations

from pathlib import Path

p = Path('data.txt')

# Check existence
p.exists()      # True/False
p.is_file()     # True/False
p.is_dir()      # True/False

# Read/write
content = p.read_text()           # Read entire file
p.write_text('Hello, World!')    # Write string

# Binary
data = p.read_bytes()            # Read as bytes
p.write_bytes(b'Binary data')   # Write bytes

# Create directories
Path('new/dir').mkdir(parents=True, exist_ok=True)

# List directory
for item in Path('.').iterdir():
    print(item.name)

# Glob patterns
for py_file in Path('.').glob('**/*.py'):  # Recursive
    print(py_file)
for py_file in Path('.').glob('*.py'):  # Current dir only
    print(py_file)

Practical Examples

from pathlib import Path
import json

# Find all Python files and count lines
def count_lines(directory):
    total = 0
    for py_file in Path(directory).glob('**/*.py'):
        total += len(py_file.read_text().splitlines())
    return total

# Process JSON files
def load_all_json(directory):
    data = []
    for json_file in Path(directory).glob('*.json'):
        data.append(json.loads(json_file.read_text()))
    return data

# Safe file operations
def safe_read(path, default=None):
    p = Path(path)
    if not p.exists():
        return default
    return p.read_text()

pathlib vs os.path

# os.path (old style)
import os
path = os.path.join('data', 'users', 'file.txt')
name = os.path.basename(path)
ext = os.path.splitext(path)[1]

# pathlib (modern, preferred)
from pathlib import Path
path = Path('data') / 'users' / 'file.txt'
name = path.name
ext = path.suffix

# pathlib is more readable and Pythonic