Concepts / File Input and Output

File Input and Output

Next, we will learn how to deal with input/output and how to access files in Python.

  • Programming

Why Files Matter in Programs

Every program you write exists in memory only while it runs. Once the program stops, all variables and data disappear. But many real-world programs need to persist data: a banking application must save account balances, a game must store high scores, a data analysis tool must load measurements from yesterday's experiment. This is where files come in. Files are the bridge between your program's temporary memory and permanent storage on disk. The ability to create, read, and write files is essential to many programs.

File Input and Output (I/O) is the mechanism by which programs interact with data stored on disk. Without file I/O, your program cannot save work, load configuration, or process stored data.

The File I/O Workflow

Every interaction with a file follows a predictable sequence. First, your program must open the file, which tells the operating system you want access to it and establishes a connection. Next, your program performs operations: reading data from the file into memory, or writing data from memory into the file. Finally, your program must close the file, which releases the connection and ensures all data is safely written to disk. This three-step pattern—open, operate, close—is fundamental to all file handling.

Program startsOpen fileFile connection establishedRead or write dataFile pointer moves throughfileClose fileConnection released, datasavedFile safely stored ondisk
What sequence of steps happens when a program interacts with a file, and what state is the file in at each step?

Opening a File and Choosing a Mode

When you open a file in Python, you must specify a mode that tells the operating system what you intend to do with it. The mode determines whether you can read, write, or both, and critically, what happens to any existing content in the file. Choosing the wrong mode can accidentally erase data or cause your program to fail when it tries to write to a read-only file.

ModePurposeFile Must Exist?What Happens to Existing Content
rRead onlyYesContent is preserved; file pointer starts at beginning
wWrite onlyNo (created if missing)Existing content is completely erased; file is truncated to zero bytes
aAppendNo (created if missing)Existing content is preserved; file pointer starts at the end
r+Read and writeYesContent is preserved; file pointer starts at beginning
w+Write and readNo (created if missing)Existing content is completely erased

The File Pointer and How It Moves

When a file is open, the operating system maintains a file pointer—a position marker that tracks where in the file the next read or write operation will occur. Think of it like a bookmark in a book: it marks your current location. When you read data, the pointer advances past the bytes you just read. When you write data, the pointer advances past the bytes you just wrote. Understanding the pointer's position is crucial because it determines what data you will read next or where new data will be written.

points here initiallyafter reading 2 bytesHbyte 0pointer (start)ebyte 1lbyte 2pointer (after read)lbyte 3obyte 4
Where is the file pointer in memory, and how does it move as data is read or written?

In read mode, the pointer starts at byte 0 (the beginning). Each read operation advances the pointer. In append mode, the pointer starts at the end of the file. In write mode, the file is empty, so the pointer starts at byte 0.

Context Managers: Safe File Handling

Python provides a feature called a context manager, invoked using the 'with' statement, that automatically handles opening and closing files. When you use 'with', Python guarantees that the file will be closed at the end of the block, even if an error occurs. This prevents resource leaks and ensures data is written to disk. Without a context manager, you must manually close the file, and if your code crashes before the close statement, the file remains open and data may be lost.

no close() callautomatic cleanupFile openedFile opened in'with' blockRead/write operationsRead/write operationsError occursError occursFile still open (datamay be lost)File automaticallyclosed (data saved)
What happens to the file when using 'with' versus manual open/close, and why does it matter?

Always use the 'with' statement when working with files. It is the standard Python idiom and eliminates the risk of forgetting to close a file. Reserve manual open() and close() calls only for advanced scenarios where you need fine-grained control over the file's lifetime.

Reading File Content

Python provides several methods to read data from a file, each suited to different situations. The read() method reads the entire file into a single string, useful for small files but wasteful for large ones. The readline() method reads one line at a time, advancing the file pointer after each call. The readlines() method reads all lines into a list of strings. The most Pythonic approach is to iterate directly over the file object, which yields one line at a time without loading the entire file into memory.

Reading a File Line by Line

You have a file named 'scores.txt' containing three lines: '85', '92', '78'. Write code to read the file and print each score.

Open the file in read mode: Use the 'with' statement and open() with mode 'r'. The file object is assigned to the variable 'f'.

Iterate over the file object: When you iterate directly over an open file, Python yields one line at a time. The newline character at the end of each line is included in the string.

Strip whitespace and print: Use the strip() method to remove the trailing newline, then print the cleaned line.

File automatically closes: When the 'with' block ends, Python automatically closes the file, even if the loop completes or an error occurs.

The output is: 85, 92, 78 (each on a separate line), and the file is safely closed.

python
Output (expected)
85
92
78

Writing and Appending Data

Writing to a file is similar to reading, but uses the write() method instead of read(). The write() method takes a string and writes it to the file at the current file pointer position. In write mode ('w'), the file is truncated first, so the pointer starts at byte 0 and any new data overwrites from the beginning. In append mode ('a'), the pointer starts at the end, so new data is added after existing content. Remember that write() does not automatically add newlines; you must include '\n' in your string if you want line breaks.

Writing to a File

Create a file named 'log.txt' and write three log messages, each on a separate line.

Open the file in write mode: Use 'with open('log.txt', 'w')'. Since the file doesn't exist, it is created. If it did exist, its content would be erased.

Write the first message: Call f.write() with the string 'Starting program\n'. The \n is essential; without it, all messages would be on one line.

Write the second and third messages: Call f.write() twice more with the remaining messages, each ending with \n.

File closes and data is saved: When the 'with' block ends, the file is closed and all written data is flushed to disk.

The file 'log.txt' now contains three lines: 'Starting program', 'Processing data', 'Finished'.

python

To add data to an existing file without erasing it, use append mode ('a'). The file pointer starts at the end, so new data is added after the existing content. This is useful for log files where you want to record events over time without losing previous entries.

python

Common Mistakes with File I/O

  • Forgetting to close the file after manual open()

    The file remains open, consuming system resources. If the program crashes or runs for a long time, the operating system may run out of available file handles. Additionally, if you later try to write to the same file from another part of your program, the changes may not be visible because the file is still held open.

    Fix: Use the 'with' statement: with open('data.txt', 'r') as f: data = f.read()

  • Using write mode ('w') when you meant to append

    If 'log.txt' already exists with previous entries, opening it in write mode immediately erases all existing content. You lose all historical data.

    Fix: Use append mode ('a') instead: with open('log.txt', 'a') as f:

  • Trying to read from a file that doesn't exist

    Opening a non-existent file in read mode raises a FileNotFoundError. Your program crashes unless you handle the exception.

    Fix: Check if the file exists first, or use try/except to catch the error. Alternatively, use mode 'r+' or 'a' which create the file if it doesn't exist.

  • Forgetting to strip newlines when reading lines

    Each line read from the file includes the trailing newline character. When you print it, you get an extra blank line because print() also adds a newline by default.

    Fix: Use strip(): print(line.strip())

  • Not including newlines in write() calls

    All three lines are written consecutively without line breaks, resulting in 'Line 1Line 2Line 3' on a single line in the file.

    Fix: Add '\n' to each write(): f.write('Line 1\n')

Choosing the Right Approach for Your Task

TaskBest MethodWhy
Read a small file all at onceread()Simple and fast for files that fit in memory
Process a large file line by lineIterate over file objectMemory-efficient; only one line is in memory at a time
Read all lines into a listreadlines()Useful if you need random access to lines or want to process them in a specific order
Create a new file or overwrite existingMode 'w'Clears the file and starts fresh
Add data to an existing fileMode 'a'Preserves existing content and appends new data at the end
Read and write to the same fileMode 'r+' or 'w+'Allows both operations; 'r+' preserves content, 'w+' truncates

Practice: Building a Simple Data Logger

MEDIUM

Write a program that simulates a simple data logger. Your program should: (1) Open a file named 'sensor_data.txt' in append mode, (2) Write three simulated sensor readings to the file, each on a separate line, with the format 'Temperature: X degrees', (3) Close the file, (4) Open the file again in read mode and print all the readings. Use the 'with' statement for all file operations. After running your program twice, verify that the file contains six readings (three from each run), not just three.

Hints
  • Remember to include '\n' at the end of each line you write
  • Use append mode ('a') so that the second run adds to the file rather than overwriting it
  • Iterate directly over the file object when reading, or use readlines()
  • Strip newlines when printing to avoid extra blank lines

Summary

  1. File I/O follows a three-step pattern: open the file, perform read or write operations, and close the file. The 'with' statement automates the closing step and ensures safe resource cleanup.
  2. File modes determine what operations are allowed and what happens to existing content. Mode 'r' reads only, 'w' writes and erases existing content, 'a' appends to the end, and 'r+' and 'w+' allow both reading and writing.
  3. The file pointer is a position marker that tracks where the next read or write will occur. It starts at byte 0 in read and write modes, and at the end of the file in append mode. Each read or write operation advances the pointer.
  4. Python provides multiple ways to read files: read() for the entire file, readline() for one line at a time, readlines() for all lines as a list, and direct iteration for memory-efficient line-by-line processing.
  5. Always use the 'with' statement to open files. It is the standard Python idiom, prevents resource leaks, and handles errors gracefully. Never forget to include newline characters ('\n') when writing multiple lines.

Key Takeaways

  • File I/O is the mechanism by which programs interact with persistent data on disk. Every file operation follows the pattern: open, operate, close.
  • File modes control what operations are allowed and what happens to existing content. Write mode ('w') erases the file; append mode ('a') adds to the end; read mode ('r') reads only.
  • Use the 'with' statement to safely open and close files. It automatically closes the file even if an error occurs, preventing resource leaks and data loss.
  • The file pointer tracks the current position in the file. It advances with each read or write operation, determining where the next operation will occur.
  • Choose your read method based on your needs: read() for small files, iteration for large files, and readlines() when you need random access to lines.