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