On this page
article
File Handling in Python
Read and write files, work with paths via pathlib, handle CSV and JSON, and manage binary files in Python.
File I/O is essential for reading config, processing data, and saving results. Python provides built-in tools for text, structured, and binary files.
Reading and Writing Text Files
# Write
with open("output.txt", "w", encoding="utf-8") as f:
f.write("Line 1\n")
f.write("Line 2\n")
# Read entire file
with open("output.txt", "r", encoding="utf-8") as f:
content = f.read()
# Read line by line (memory-efficient for large files)
with open("output.txt", "r") as f:
for line in f:
print(line.strip())
# Read all lines into a list
with open("output.txt") as f:
lines = f.readlines()
Always use with open(...) — files close automatically, even on errors.
File Modes
| Mode | Description |
|---|---|
r |
Read (default) |
w |
Write (overwrites) |
a |
Append |
x |
Create (fails if exists) |
r+ |
Read and write |
rb, wb |
Binary read/write |
pathlib — Modern Path Handling
from pathlib import Path
data_dir = Path("data")
data_dir.mkdir(exist_ok=True)
file_path = data_dir / "report.txt"
file_path.write_text("Hello, pathlib!", encoding="utf-8")
content = file_path.read_text(encoding="utf-8")
for csv_file in data_dir.glob("*.csv"):
print(csv_file.name)
print(file_path.exists())
print(file_path.stat().st_size)
print(file_path.parent)
print(file_path.suffix)
Prefer pathlib over os.path for new code.
CSV Files
import csv
# Reading
with open("employees.csv", newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
print(row["name"], row["salary"])
# Writing
employees = [
{"name": "Alice", "department": "Engineering", "salary": 90000},
{"name": "Bob", "department": "Sales", "salary": 75000},
]
with open("output.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["name", "department", "salary"])
writer.writeheader()
writer.writerows(employees)
JSON Files
import json
data = {
"name": "Alice",
"age": 30,
"skills": ["Python", "SQL"],
"active": True,
}
# Write
with open("user.json", "w") as f:
json.dump(data, f, indent=2)
# Read
with open("user.json") as f:
loaded = json.load(f)
# String serialization
json_str = json.dumps(data)
parsed = json.loads(json_str)
JSON only supports: objects, arrays, strings, numbers, booleans, and null.
Binary Files
# Copy a binary file
with open("photo.jpg", "rb") as src, open("copy.jpg", "wb") as dst:
dst.write(src.read())
# Read bytes in chunks
with open("large_file.bin", "rb") as f:
while chunk := f.read(8192):
process(chunk)
Working with Directories
from pathlib import Path
import shutil
src = Path("old_folder")
dst = Path("new_folder")
dst.mkdir(parents=True, exist_ok=True)
shutil.copy("file.txt", dst / "file.txt")
shutil.move(str(src / "archive"), dst / "archive")
shutil.rmtree("temp_dir") # delete directory tree
Temporary Files
import tempfile
import os
with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".txt") as f:
f.write("temporary data")
temp_path = f.name
# use temp_path...
os.remove(temp_path)
Error Handling
from pathlib import Path
def safe_read(path):
file = Path(path)
if not file.exists():
raise FileNotFoundError(f"No such file: {path}")
if file.stat().st_size > 10_000_000:
raise ValueError("File too large (>10MB)")
return file.read_text(encoding="utf-8")
Best Practices
- Always specify encoding —
encoding="utf-8"for text files - Use context managers —
with open(...)orPath.read_text() - Stream large files — read line-by-line or in chunks
- Use pathlib — cleaner than string path concatenation
- Validate before processing — check existence, size, format
File handling connects your Python programs to the real world of data on disk.