File Handling – Reading and Writing Files
Why this matters
Programs forget everything when they stop running. Files let your code remember things: scores, notes, settings, stories—anything made of text or bytes.
Core ideas
- Files and paths: A file lives in a folder (directory). A path is "where" it lives (like data/notes.txt).
- Opening files: Use open(path, mode, encoding). Common modes:
- 'r' = read (file must exist)
- 'w' = write (creates or overwrites)
- 'a' = append (adds to the end)
- Always close files: The with statement closes files for you, even if errors happen.
- Reading text: read() gets the whole file; for line in file reads line by line; readline() gets one line.
- Writing text: write("text") writes a string. Remember to add "\n" for new lines.
- Encoding: Use encoding="utf-8" for text files.
- Safer paths: Use pathlib.Path to build paths that work across systems.
- Errors: FileNotFoundError happens if you try to read a file that isn't there.
Code examples
1) Write to a new file (overwrites if it exists)
# Creates (or overwrites) greetings.txt
with open("greetings.txt", "w", encoding="utf-8") as f:
f.write("Hello, PyVerse!\n")
f.write("This is a saved line.\n")2) Append to a file (keeps old content and adds more)
with open("greetings.txt", "a", encoding="utf-8") as f:
f.write("Another line at the end.\n")3) Read the whole file at once
with open("greetings.txt", "r", encoding="utf-8") as f:
text = f.read()
print(text)4) Read line by line (better for big files)
with open("greetings.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.strip()) # strip() removes the trailing newline5) Write many lines from a list (remember the newline!)
names = ["Ada", "Linus", "Guido"]
with open("names.txt", "w", encoding="utf-8") as f:
for name in names:
f.write(name + "\n")6) Build paths safely with pathlib
from pathlib import Path
data_folder = Path("data")
data_folder.mkdir(exist_ok=True) # make folder if it doesn't exist
file_path = data_folder / "notes.txt"
with file_path.open("w", encoding="utf-8") as f:
f.write("Saved in the data folder!\n")7) Friendly error handling
try:
with open("missing.txt", "r", encoding="utf-8") as f:
print(f.read())
except FileNotFoundError:
print("Oops! missing.txt was not found.")Mini Project: Personal Journal (text-based)
Build a tiny journal app that saves entries to a file. You'll practice reading, writing, appending, and searching.
Requirements
- Create or open journal.txt.
- Menu:
- Add entry: ask for text, save with a timestamp.
- Read entries: show all saved entries.
- Search entries: ask for a keyword and show matching lines.
- Quit.
- Handle the case where the file doesn't exist yet.
Starter code
from pathlib import Path
from datetime import datetime
JOURNAL = Path("journal.txt")
def add_entry():
text = input("Write your entry: ").strip()
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M")
# TODO: open JOURNAL in append mode and write "[timestamp] text\n"
with JOURNAL.open("a", encoding="utf-8") as f:
f.write(f"[{timestamp}] {text}\n")
print("Entry saved.")
def read_entries():
if not JOURNAL.exists():
print("No entries yet.")
return
with JOURNAL.open("r", encoding="utf-8") as f:
print("---- Journal ----")
print(f.read())
print("-----------------")
def search_entries():
if not JOURNAL.exists():
print("No entries to search.")
return
keyword = input("Keyword: ").strip().lower()
print(f"Results for '{keyword}':")
found = False
with JOURNAL.open("r", encoding="utf-8") as f:
for line in f:
if keyword in line.lower():
print(line.strip())
found = True
if not found:
print("No matches found.")
def main():
while True:
print("\n1) Add entry 2) Read entries 3) Search 4) Quit")
choice = input("Choose: ").strip()
if choice == "1":
add_entry()
elif choice == "2":
read_entries()
elif choice == "3":
search_entries()
elif choice == "4":
print("Goodbye!")
break
else:
print("Please choose 1-4.")
if __name__ == "__main__":
main()Challenge extensions
- Add an option to export only today's entries to today.txt.
- Count how many entries are in the journal and show the count.
- Prevent empty entries.
Summary
- Use open(path, mode, encoding) and prefer with to auto-close files.
- 'r' reads, 'w' overwrites, 'a' appends.
- read() gets all text; loop line by line for large files.
- write() saves strings; add "\n" for new lines.
- Use pathlib.Path for safe, clean paths.
- Handle FileNotFoundError to keep programs friendly.
With these skills, your programs can remember, share, and analyze information across runs—welcome to the world of persistent data!