File Basics: Reading and Writing Text Files
Welcome to the foundation of data persistence! Files allow your programs to remember information between runs. Think of files as digital notebooks where you can write down information and read it back later.
Opening and Closing Files
The Basic Way (Not Recommended)
# Open file
file = open("example.txt", "r")
# Do something with file
content = file.read()
print(content)
# Don't forget to close! (easy to forget)
file.close()
The Safe Way (Recommended)
# File automatically closes when done
with open("example.txt", "r") as file:
content = file.read()
print(content)
# File is automatically closed here
Reading Text Files
Reading Entire File
with open("story.txt", "r") as file:
content = file.read()
print("File content:")
print(content)
print(f"Characters in file: {len(content)}")
Reading Line by Line
with open("story.txt", "r") as file:
line_count = 0
for line in file:
line_count += 1
print(f"Line {line_count}: {line.strip()}")
print(f"Total lines: {line_count}")
Reading Specific Number of Characters
with open("story.txt", "r") as file:
# Read first 100 characters
first_100 = file.read(100)
print("First 100 characters:")
print(first_100)
print("-" * 50)
# Read next 100 characters
next_100 = file.read(100)
print("Next 100 characters:")
print(next_100)
Reading Lines as List
with open("story.txt", "r") as file:
lines = file.readlines()
print(f"File has {len(lines)} lines")
# Print first and last lines
if lines:
print(f"First line: {lines[0].strip()}")
print(f"Last line: {lines[-1].strip()}")
# Print lines with line numbers
print("\nAll lines:")
for i, line in enumerate(lines, 1):
print(f"{i:2d}: {line.strip()}")
Writing Text Files
Writing to a New File
with open("output.txt", "w") as file:
file.write("Hello, World!\n")
file.write("This is my first file.\n")
file.write("Python file handling is fun!")
print("File 'output.txt' created successfully!")
Appending to Existing File
# First, create initial content
with open("log.txt", "w") as file:
file.write("Program started\n")
# Then append more content
with open("log.txt", "a") as file:
file.write("Task 1 completed\n")
file.write("Task 2 completed\n")
file.write("Program finished\n")
print("Log entries added to 'log.txt'")
Writing Multiple Lines
shopping_list = [
"Apples",
"Bananas",
"Milk",
"Bread",
"Eggs"
]
with open("shopping.txt", "w") as file:
file.write("My Shopping List\n")
file.write("=" * 20 + "\n")
for item in shopping_list:
file.write(f"β {item}\n")
file.write(f"\nTotal items: {len(shopping_list)}")
print("Shopping list saved to 'shopping.txt'")
File Modes
Common File Modes
# "r" - Read (default) - file must exist
# "w" - Write - creates new file or overwrites existing
# "a" - Append - adds to end of file
# "x" - Exclusive creation - fails if file exists
# Text modes (default)
# "rt" - Read text (same as "r")
# "wt" - Write text (same as "w")
# "at" - Append text (same as "a")
# Binary modes
# "rb" - Read binary
# "wb" - Write binary
# "ab" - Append binary
Examples of Different Modes
# Write mode - overwrites file
with open("test.txt", "w") as file:
file.write("First write\n")
# Append mode - adds to file
with open("test.txt", "a") as file:
file.write("Second write\n")
# Read mode - reads file
with open("test.txt", "r") as file:
content = file.read()
print("File content:")
print(content)
# Exclusive mode - only creates if doesn't exist
try:
with open("new_file.txt", "x") as file:
file.write("This file was just created!\n")
print("File 'new_file.txt' created successfully!")
except FileExistsError:
print("File 'new_file.txt' already exists!")
File Position and Seeking
Understanding File Position
with open("story.txt", "r") as file:
print(f"Initial position: {file.tell()}")
# Read 10 characters
chunk = file.read(10)
print(f"Read: '{chunk}'")
print(f"Position after reading: {file.tell()}")
# Read another 10 characters
chunk2 = file.read(10)
print(f"Read: '{chunk2}'")
print(f"Position after second read: {file.tell()}")
Moving File Position
with open("story.txt", "r") as file:
# Read first line
first_line = file.readline()
print(f"First line: {first_line.strip()}")
# Get current position
pos = file.tell()
print(f"Position after first line: {pos}")
# Skip to position 50
file.seek(50)
print(f"Seeked to position: {file.tell()}")
# Read from new position
chunk = file.read(20)
print(f"Read from position 50: '{chunk}'")
# Go back to beginning
file.seek(0)
print(f"Back to beginning: {file.tell()}")
# Read first line again
first_line_again = file.readline()
print(f"First line again: {first_line_again.strip()}")
Handling File Errors
File Not Found Error
filename = "nonexistent_file.txt"
try:
with open(filename, "r") as file:
content = file.read()
print(content)
except FileNotFoundError:
print(f"Error: The file '{filename}' was not found.")
print("Please check the filename and try again.")
Permission Error
# Try to write to a directory (will fail)
try:
with open("/root/secret_file.txt", "w") as file:
file.write("This won't work!")
except PermissionError:
print("Error: Permission denied. Cannot write to this location.")
except OSError as e:
print(f"OS Error: {e}")
Comprehensive Error Handling
def safe_read_file(filename):
"""Safely read a file with comprehensive error handling."""
try:
with open(filename, "r") as file:
return file.read()
except FileNotFoundError:
return f"Error: File '{filename}' not found."
except PermissionError:
return f"Error: Permission denied for '{filename}'."
except IsADirectoryError:
return f"Error: '{filename}' is a directory, not a file."
except UnicodeDecodeError:
return f"Error: '{filename}' contains invalid characters."
except Exception as e:
return f"Unexpected error reading '{filename}': {e}"
# Test the function
print(safe_read_file("story.txt"))
print(safe_read_file("nonexistent.txt"))
Working with File Paths
Basic Path Operations
import os
# Get current working directory
current_dir = os.getcwd()
print(f"Current directory: {current_dir}")
# Check if file exists
if os.path.exists("story.txt"):
print("story.txt exists")
else:
print("story.txt does not exist")
# Check if path is file or directory
if os.path.isfile("story.txt"):
print("story.txt is a file")
elif os.path.isdir("story.txt"):
print("story.txt is a directory")
# Get file size
if os.path.exists("story.txt"):
size = os.path.getsize("story.txt")
print(f"File size: {size} bytes")
Building Paths
import os
# Join path components (cross-platform)
data_file = os.path.join("data", "user_data.txt")
print(f"Data file path: {data_file}")
# Join multiple components
config_file = os.path.join("app", "config", "settings.json")
print(f"Config file path: {config_file}")
# Get directory and filename
full_path = "/home/user/documents/letter.txt"
directory = os.path.dirname(full_path)
filename = os.path.basename(full_path)
print(f"Directory: {directory}")
print(f"Filename: {filename}")
# Split extension
name, extension = os.path.splitext("document.pdf")
print(f"Name: {name}, Extension: {extension}")
Real-World Examples
Example 1: Simple Address Book
def add_contact(name, phone, email):
"""Add a contact to the address book."""
with open("contacts.txt", "a") as file:
file.write(f"{name},{phone},{email}\n")
print(f"Contact {name} added successfully!")
def view_contacts():
"""Display all contacts."""
try:
with open("contacts.txt", "r") as file:
contacts = file.readlines()
if not contacts:
print("No contacts found.")
return
print("Address Book:")
print("-" * 50)
for contact in contacts:
name, phone, email = contact.strip().split(",")
print("15")
print(f"Total contacts: {len(contacts)}")
except FileNotFoundError:
print("Address book not found. Add some contacts first!")
# Usage
add_contact("Alice Johnson", "555-0123", "alice@email.com")
add_contact("Bob Smith", "555-0456", "bob@email.com")
add_contact("Charlie Brown", "555-0789", "charlie@email.com")
view_contacts()
Example 2: Text File Word Counter
def count_words_in_file(filename):
"""Count words in a text file."""
try:
with open(filename, "r") as file:
text = file.read()
# Convert to lowercase and split into words
words = text.lower().split()
# Remove punctuation from words
clean_words = []
for word in words:
# Remove common punctuation
clean_word = word.strip(".,!?\"'()[]{}:;")
if clean_word: # Only add non-empty words
clean_words.append(clean_word)
# Count word frequencies
word_count = {}
for word in clean_words:
word_count[word] = word_count.get(word, 0) + 1
return {
"total_words": len(clean_words),
"unique_words": len(word_count),
"word_frequencies": word_count
}
except FileNotFoundError:
return f"Error: File '{filename}' not found."
except Exception as e:
return f"Error reading file: {e}"
# Create a sample text file
sample_text = """
The quick brown fox jumps over the lazy dog. The fox is quick and the dog is lazy.
Python programming is fun and powerful. Programming requires practice and patience.
"""
with open("sample_text.txt", "w") as file:
file.write(sample_text)
# Analyze the file
result = count_words_in_file("sample_text.txt")
if isinstance(result, dict):
print(f"Total words: {result['total_words']}")
print(f"Unique words: {result['unique_words']}")
print("\nTop 5 most frequent words:")
sorted_words = sorted(result['word_frequencies'].items(),
key=lambda x: x[1], reverse=True)
for word, count in sorted_words[:5]:
print(f" {word}: {count}")
else:
print(result)
Example 3: Log File Writer
import datetime
def log_message(message, level="INFO"):
"""Write a message to the log file with timestamp."""
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_entry = f"[{timestamp}] {level}: {message}\n"
with open("app.log", "a") as file:
file.write(log_entry)
def log_error(message):
"""Log an error message."""
log_message(message, "ERROR")
def log_warning(message):
"""Log a warning message."""
log_message(message, "WARNING")
def read_recent_logs(lines=10):
"""Read the most recent log entries."""
try:
with open("app.log", "r") as file:
all_lines = file.readlines()
# Get last n lines
recent_lines = all_lines[-lines:] if len(all_lines) > lines else all_lines
print(f"Last {len(recent_lines)} log entries:")
print("-" * 60)
for line in recent_lines:
print(line.strip())
except FileNotFoundError:
print("No log file found.")
# Usage
log_message("Application started")
log_message("User login successful", "INFO")
log_warning("Disk space running low")
log_error("Database connection failed")
log_message("Application shutdown")
read_recent_logs()
Best Practices
1. Always Use with Statement
# β
Good
with open("file.txt", "r") as file:
content = file.read()
# β Bad - may leak file handles
file = open("file.txt", "r")
content = file.read()
file.close() # Easy to forget!
2. Handle File Errors
# β
Good
try:
with open("data.txt", "r") as file:
data = file.read()
except FileNotFoundError:
data = "Default data"
except PermissionError:
print("Permission denied")
data = None
3. Use Meaningful File Modes
# β
Clear intent
with open("config.json", "r") as file: # Read existing
pass
with open("output.txt", "w") as file: # Create/overwrite
pass
with open("log.txt", "a") as file: # Add to existing
pass
4. Check File Existence
import os
# β
Check before reading
if os.path.exists("important.txt"):
with open("important.txt", "r") as file:
content = file.read()
else:
content = "Default content"
Practice Exercises
Exercise 1: Personal Diary
Create a diary application that:
- Add new diary entries with dates
- View all entries
- Search entries by keyword
- Save entries to a text file
Exercise 2: Recipe Manager
Build a recipe storage system:
- Add recipes (name, ingredients, instructions)
- View all recipes
- Search recipes by ingredient
- Save/load recipes from file
Exercise 3: Grade Calculator
Create a grade calculator that:
- Input student names and grades
- Calculate averages
- Assign letter grades
- Save results to file
- Load previous results
Exercise 4: Simple Backup System
Build a backup utility that:
- Copy text files from one directory to another
- Log backup operations
- Handle errors gracefully
- Show backup statistics
Exercise 5: Text File Analyzer
Create a file analyzer that:
- Count lines, words, characters
- Find most common words
- Analyze sentence structure
- Generate summary reports
Summary
File basics enable data persistence:
Reading Files:
with open(filename, "r") as file:- safe file openingfile.read()- entire filefile.readline()- one linefor line in file:- iterate through lines
Writing Files:
open(filename, "w")- write mode (overwrites)open(filename, "a")- append mode (adds to end)file.write(text)- write text
File Modes:
"r"- read"w"- write (overwrite)"a"- append"x"- exclusive creation
Error Handling:
FileNotFoundError- file doesnβt existPermissionError- no access rightsIsADirectoryError- path is directory
Best Practices:
- Always use
withstatement - Handle exceptions appropriately
- Check file existence when needed
- Use descriptive file modes
Next: CSV and JSON Files - structured data formats! π