Table of Contents
- Understanding File I/O Basics
- What is File I/O?
- Why File I/O Matters in Python
- Opening and Closing Files
- The
open()Function - File Modes
- The
withStatement (Context Manager)
- The
- Reading Files
read(): Read Entire Filereadline(): Read One Linereadlines(): Read All Lines into a List- Iterating Over Lines
- Reading Binary Files
- Writing Files
write(): Write Stringswritelines(): Write Iterables- Modes: Overwrite (
w), Append (a), and Exclusive Create (x) - Writing Binary Files
- File Paths: Absolute vs. Relative
- The
osModule - The
pathlibModule (Modern Approach)
- The
- Handling File Exceptions
- Common Exceptions
try-exceptBlocks for File I/O
- Advanced File Formats
- Working with CSV Files
- Working with JSON Files
- Other File Operations
- Seeking and Truncating
- Checking File Existence
- Deleting Files
- File Metadata
- Best Practices for File I/O
- Conclusion
- References
1. Understanding File I/O Basics
What is File I/O?
File I/O refers to the process of reading data from files (input) and writing data to files (output) on a storage device (e.g., hard drive, SSD). Files can store text, images, binary data, or structured formats like CSV/JSON.
Why File I/O Matters in Python
Python’s file I/O capabilities are essential for:
- Loading configuration settings (e.g.,
.envfiles). - Processing large datasets (e.g., CSV logs).
- Persisting application state (e.g., saving user preferences).
- Generating reports or exporting data (e.g., JSON/Excel).
2. Opening and Closing Files
Before reading or writing a file, you must open it. Python’s built-in open() function handles this, and you must explicitly close the file afterward to free system resources—unless using a context manager (more on that later).
The open() Function
Syntax:
file_object = open(file_path, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
Key parameters:
file_path: Path to the file (relative or absolute).mode: Specifies the purpose of opening the file (read, write, append, etc.).encoding: Character encoding (e.g.,'utf-8'for text files).
File Modes
The mode parameter determines how the file is opened. Common modes:
| Mode | Description |
|---|---|
'r' | Read (default). Opens file for reading; error if file doesn’t exist. |
'w' | Write. Opens file for writing; creates file if it doesn’t exist, overwrites if it does. |
'a' | Append. Opens file for writing; appends to end if file exists, creates if not. |
'x' | Exclusive create. Creates file; error if file exists. |
'b' | Binary mode (e.g., 'rb' for reading binary files like images). |
't' | Text mode (default, e.g., 'rt' for reading text files). |
'+' | Read/write mode (e.g., 'r+' for reading and writing). |
Closing Files Explicitly
Always close files after use to avoid resource leaks:
file = open("example.txt", "r")
# ... read/write operations ...
file.close() # Critical!
The with Statement (Context Manager)
The with statement automatically closes the file, even if an error occurs. This is the recommended approach:
with open("example.txt", "r") as file:
# Work with file here
content = file.read()
# File is closed automatically after the block
3. Reading Files
Once a file is opened in read mode ('r'), use these methods to read content:
read(): Read Entire File
Reads the entire content as a single string.
Example:
with open("example.txt", "r") as file:
content = file.read()
print(content)
Output (if example.txt contains “Hello, World!“):
Hello, World!
readline(): Read One Line
Reads a single line from the file (including the newline character \n).
Example:
with open("example.txt", "r") as file:
line1 = file.readline() # Reads first line
line2 = file.readline() # Reads second line
print(line1) # "Hello, World!\n"
print(line2) # "Python File I/O is fun!\n" (if second line exists)
readlines(): Read All Lines into a List
Returns a list where each element is a line from the file.
Example:
with open("example.txt", "r") as file:
lines = file.readlines() # List of lines
print(lines) # ["Hello, World!\n", "Python File I/O is fun!\n"]
Iterating Over Lines
Loop directly over the file object for memory-efficient line-by-line reading (avoids loading the entire file into memory):
with open("example.txt", "r") as file:
for line in file:
print(line.strip()) # .strip() removes newline characters
Output:
Hello, World!
Python File I/O is fun!
Reading Binary Files
For non-text files (images, PDFs), use binary mode ('rb'):
with open("image.jpg", "rb") as img_file:
binary_data = img_file.read() # Bytes object
4. Writing Files
To write to a file, use modes like 'w' (write), 'a' (append), or 'x' (exclusive create).
write(): Write Strings
Writes a string to the file.
Example (overwrite with 'w'):
with open("output.txt", "w") as file:
file.write("First line\n")
file.write("Second line\n")
output.txt now contains:
First line
Second line
writelines(): Write Iterables
Writes a list/tuple of strings (does not add newlines automatically):
lines = ["Apple\n", "Banana\n", "Cherry\n"]
with open("fruits.txt", "w") as file:
file.writelines(lines)
Append Mode ('a')
Adds content to the end of the file instead of overwriting:
with open("output.txt", "a") as file:
file.write("Third line\n") # Appended to output.txt
Exclusive Create Mode ('x')
Creates a new file but raises FileExistsError if the file already exists:
try:
with open("new_file.txt", "x") as file:
file.write("This file is unique!")
except FileExistsError:
print("File already exists!")
Writing Binary Files
Use 'wb' to write binary data (e.g., saving an image):
binary_data = b"Raw binary content" # Bytes literal
with open("binary_file.bin", "wb") as file:
file.write(binary_data)
5. File Paths: Absolute vs. Relative
Absolute Paths
Full path from the root directory (e.g., C:\Users\Name\file.txt on Windows, /home/user/file.txt on Linux/macOS).
Relative Paths
Path relative to the current working directory (CWD). For example:
./data/file.txt:datafolder in the CWD.../parent/file.txt:file.txtin the parent directory of the CWD.
The os Module
Use os.path for path manipulation (legacy approach):
import os
# Get current working directory
cwd = os.getcwd()
print(cwd) # e.g., '/home/user/projects'
# Join paths (handles OS-specific separators)
file_path = os.path.join(cwd, "data", "file.txt")
print(file_path) # '/home/user/projects/data/file.txt' (Linux)
The pathlib Module (Modern Approach)
Python 3.4+ introduced pathlib, an object-oriented alternative to os.path:
from pathlib import Path
# Create a Path object
file_path = Path("data") / "file.txt" # Uses / operator for joining
# Check if file exists
if file_path.exists():
print(f"File exists: {file_path}")
# Read file
with open(file_path, "r") as file:
content = file.read()
6. Handling File Exceptions
File operations can fail (e.g., missing file, permission denied). Use try-except blocks to handle errors gracefully.
Common Exceptions
| Exception | Scenario |
|---|---|
FileNotFoundError | File does not exist (e.g., open("missing.txt", "r")). |
PermissionError | No read/write permission for the file. |
IsADirectoryError | Trying to open a directory as a file. |
UnicodeDecodeError | Decoding binary data as text (e.g., 'rb' mode missing). |
Example: Error Handling
file_path = "example.txt"
try:
with open(file_path, "r") as file:
content = file.read()
print("File read successfully!")
except FileNotFoundError:
print(f"Error: {file_path} not found.")
except PermissionError:
print(f"Error: No permission to read {file_path}.")
except Exception as e: # Catch-all (use sparingly)
print(f"Unexpected error: {e}")
7. Advanced File Formats
CSV Files
Use Python’s built-in csv module to work with comma-separated values (common for spreadsheets/datasets).
Reading CSV Files
import csv
with open("data.csv", "r") as file:
reader = csv.reader(file) # Reader object
for row in reader:
print(row) # List of values in each row
Using DictReader (with Headers)
with open("data.csv", "r") as file:
reader = csv.DictReader(file) # Uses first row as headers
for row in reader:
print(row["Name"], row["Age"]) # Access via column name
Writing CSV Files
with open("output.csv", "w", newline="") as file: # newline="" prevents extra blank lines
writer = csv.writer(file)
writer.writerow(["Name", "Age"]) # Header
writer.writerow(["Alice", 30])
writer.writerow(["Bob", 25])
JSON Files
JSON (JavaScript Object Notation) is ideal for structured data. Use the json module.
Reading JSON
import json
with open("data.json", "r") as file:
data = json.load(file) # Parses JSON into Python dict/list
print(data["name"]) # Access values like a Python dict
Writing JSON
data = {"name": "Alice", "age": 30, "hobbies": ["reading", "coding"]}
with open("output.json", "w") as file:
json.dump(data, file, indent=4) # indent for readability
output.json will contain:
{
"name": "Alice",
"age": 30,
"hobbies": [
"reading",
"coding"
]
}
8. Other File Operations
Seeking and Truncating
seek(offset, whence): Moves the file pointer to a specific position (e.g.,file.seek(0)to reset to start).truncate(size): Resizes the file tosizebytes (truncates content beyond that).
Example:
with open("example.txt", "r+") as file: # Read/write mode
file.seek(5) # Move pointer to 5th byte
content = file.read(3) # Read 3 bytes from current position
print(content) # e.g., 'o, ' (if file starts with "Hello, World!")
Checking File Existence
from pathlib import Path
file = Path("example.txt")
if file.exists():
print("File exists!")
else:
print("File does not exist.")
Deleting Files
Use os.remove() or pathlib.Path.unlink():
import os
os.remove("old_file.txt") # Deletes the file
# Or with pathlib:
Path("old_file.txt").unlink()
File Metadata
Get file size, modification time, etc., with os.stat() or pathlib:
from pathlib import Path
file = Path("example.txt")
print(f"Size: {file.stat().st_size} bytes")
print(f"Modified: {file.stat().st_mtime}") # Unix timestamp
9. Best Practices for File I/O
- Use
withStatements: Automatically closes files, even on errors. - Specify Encoding: Always define
encoding='utf-8'for text files to avoid platform-specific issues:with open("file.txt", "r", encoding="utf-8") as file: ... - Avoid Hard-Coded Paths: Use
pathliboros.pathfor dynamic paths. - Handle Large Files in Chunks: For files larger than memory, read/write in chunks:
with open("large_file.txt", "r") as file: while chunk := file.read(1024): # Read 1KB chunks process(chunk) - Validate File Existence: Check if a file exists before reading/writing (if needed).
- Use Specific Exceptions: Avoid broad
except Exceptionblocks; catch specific errors likeFileNotFoundError.
10. Conclusion
File I/O is a cornerstone of Python programming, enabling interaction with external data. By mastering open(), context managers, reading/writing techniques, and libraries like csv and json, you can handle everything from simple text files to complex datasets. Remember to prioritize error handling and best practices like the with statement to write robust, maintainable code.