Reading & Writing With File Handling
Almost every real Python application reads or writes files — logs, configs, datasets, reports. Python provides a clean, OS-independent file API with the built-in open() function and the with statement. This chapter covers everything from text files and binary files to reading large logs efficiently.
Overview
Open Anything
Text, JSON, CSV, images, binaries — same API.
Auto Cleanup
with ensures files are closed properly.
Streaming
Iterate line by line — process gigabytes without loading them all.
Encoding Aware
UTF-8 by default, explicit and portable.
Binary Ready
Read images, audio, and any byte stream with the same primitives.
Syntax
- Open:
open("file.txt", mode, encoding="utf-8"). - Modes:
rread,wwrite (overwrite),aappend,xcreate-new,bbinary,+read/write. - Always use the
withstatement for automatic cleanup. - Use
read(),readline(),readlines(), or iterate the file directly.
# write
with open("notes.txt", "w", encoding="utf-8") as f:
f.write("Line 1\nLine 2\n")
# read whole file
with open("notes.txt", encoding="utf-8") as f:
content = f.read()
# read line by line (memory efficient)
with open("big.log", encoding="utf-8") as f:
for line in f:
process(line)
Detailed Explanation
- File modes:
rreads (default),wwrites (truncates first),aappends,xcreates new (fails if exists). Addbfor binary or+for read/write. - The
withstatement:with open(...) as f:is the cleanest pattern. The file is closed when the block exits, even on errors — preventing resource leaks. - Reading:
read()loads everything into memory — fine for small files. For large files iterate line-by-line.readlines()returns a list of all lines. - Writing: Use
write()for a string orwritelines()for a list of strings.write()does NOT add a newline — append\nyourself. - Encoding: Always specify
encoding="utf-8"for text files. Without it, Python uses the platform default, which can cause bugs. - Binary files: Open with
"rb"or"wb"for images, audio, PDFs. Read/writebytesobjects, not strings.
Code Examples
with open("hello.txt", "w", encoding="utf-8") as f:
f.write("Hello, Python!\n")
f.write("Welcome to PBA Institute.\n")
print("Written.")
with open("hello.txt", encoding="utf-8") as f:
print(f.read())
Welcome to PBA Institute.
with open("hello.txt", encoding="utf-8") as f:
for line in f:
print(line.rstrip())
Welcome to PBA Institute.
with open("hello.txt", "a", encoding="utf-8") as f:
f.write("Another line.\n")
with open("notes.txt", encoding="utf-8") as f:
text = f.read()
print("Words:", len(text.split()))
with open("logo.png", "rb") as src, open("logo_copy.png", "wb") as dst:
dst.write(src.read())
print("Copied")
Real-World Use Cases
Log Processing
Read large log files line-by-line to extract errors.
Configuration
Read settings from .ini, .yaml or .json files.
Data Pipelines
Process CSVs of millions of records using streaming.
Media
Read/write binary files for images, audio, and video.
Backups
Copy or compress files programmatically.
Audit Trails
Append timestamps and events to log files for compliance.
Notes & Pro Tips
- Always use
with open(...)— it auto-closes files. - Specify
encoding="utf-8"for text files to avoid platform issues. - Iterate line-by-line for large files; never load gigabytes into memory.
- Use
"a"mode for appending —"w"overwrites the file. - Use
os.pathorpathlib.Pathfor cross-platform paths. - For structured data, prefer
json,csv, orpandasmodules.
Common Mistakes
- Forgetting to close: file handles leak; always use
with. - Wrong mode: opening with
"w"erases the existing content. - Encoding mismatch: reading a UTF-8 file as ASCII raises
UnicodeDecodeError. - Reading whole files needlessly: stream large files line by line.
- Mixing text and binary: write bytes to a binary file, strings to a text file.
- Hard-coded paths: use
pathlibor join withos.path.joinfor portability.
Practice Problems
- Problem 1: Write the first 10 squares to a file
squares.txt. - Problem 2: Read a file and count the number of lines, words, and characters.
- Problem 3: Copy the contents of one file into another using Python.
- Problem 4: Read a log file and print only lines containing the word 'ERROR'.
- Problem 5: Append the current date and a user message to a file each time the program runs.
- Problem 6: Read a binary image file and save a copy with a new name.
Interview Questions
- Q1. What is the role of the
withstatement in file handling? - Q2. What are the different file modes in Python?
- Q3. What's the difference between
read()andreadline()? - Q4. Why is specifying encoding important?
- Q5. How would you process a 10 GB file in Python?
- Q6. What is the difference between text mode and binary mode?
Frequently Asked Questions
- Q1: How do I open a file?
Use open(path, mode). Combine with the with statement to ensure it is closed automatically. - Q2: What does 'a' mode do?
It opens the file for appending. New writes go at the end without erasing existing content. - Q3: Why use encoding='utf-8'?
UTF-8 is the de-facto standard for text. Without specifying it, Python uses the OS default which differs across systems. - Q4: How do I check if a file exists?
Use pathlib.Path('file').exists() or os.path.exists('file') before opening. - Q5: Can I read a file in chunks?
Yes — call f.read(chunk_size) or iterate line by line for streaming. - Q6: What's the difference between text and binary mode?
Text mode returns str and applies encoding; binary mode returns bytes with no transformation.
Summary
File handling is the bridge between your program and persistent storage. With open(), the with statement, and a few mode characters, you can read or write any file safely and portably. Adopt the discipline of explicit encoding, line-by-line streaming for big files, and pathlib for paths — and you'll write file code that runs everywhere reliably.
Continue Learning
Previous
Go to Previous Chapter