File Input/Output in Python
Learning objectives
In this guide you will learn to:
- open and close files safely with
with; - read and write text files (
.txt,.csv, etc.); - iterate over the lines of a file efficiently;
- handle binary files (images, raw data);
- move around inside a file with
seek()andtell().
Introduction: Opening Files
To work with a file you must first open it with the open(filename, mode) function.
Opening Modes
The most important ones are:
'r'(Read): Reading (default). Error if the file does not exist.'w'(Write): Writing. Overwrites the file if it exists, creates it otherwise.'a'(Append): Writing at the end. Adds data without deleting existing content.'b'(Binary): Combined with the above for binary files (e.g.'rb','wb').
The with Context Manager
It is essential to always close files to release resources. In Python, the best way is to use the with block, which closes the file automatically even if an error occurs.
# DON'T DO THIS (risky if an error occurs before close)
f = open("data.txt", "r")
content = f.read()
f.close()
# DO THIS (safe and Pythonic)
with open("data.txt", "r") as f:
content = f.read()
# The file is already closed here
Text Files
Reading
There are several methods for reading the content:
read(): Reads the entire file as a single string.readline(): Reads one line at a time (including the trailing\n).readlines(): Reads all lines and returns a list of strings.- Direct iteration: The most efficient method for large files.
# Best method for iterating over a file line by line
with open("list.txt", "r") as f:
for line in f:
# line includes the newline character
print(line.strip()) # strip() removes leading/trailing whitespace and \n
Searching for specific lines with a for loop:
# The for loop is the standard way to read one line at a time.
# It does not load the entire file into memory!
with open("log.txt", "r") as f:
for line in f:
if line.startswith("ERROR:"):
print("Error found:", line.strip())
Writing
with open("output.txt", "w") as f:
f.write("First line\n") # \n must be added explicitly
f.write("Second line\n")
# Writing a list of lines
lines = ["Third\n", "Fourth\n"]
f.writelines(lines)
Example: Counting lines
count = 0
with open("log.txt", "r") as f:
for line in f:
count += 1
print(f"The file has {count} lines.")
Binary Files
Binary files (images, audio, executables) are not divided into lines and do not use encodings like UTF-8. They are read and written as sequences of bytes.
# Copying an image (byte by byte)
with open("photo.jpg", "rb") as source: # rb = read binary
data = source.read() # Reads all bytes
with open("photo_copy.jpg", "wb") as dest: # wb = write binary
dest.write(data)
Reading in chunks with a while loop — useful for large files:
# For large files, read in "chunks" until the end
CHUNK_SIZE = 4096 # Read 4 KB at a time
with open("video.mp4", "rb") as f:
while True:
data = f.read(CHUNK_SIZE)
if not data: # Empty bytes means end of file
break
# Process the data (e.g. save it, send it, etc.)
pass
Note: When reading in binary mode you get
bytesobjects (e.g.b'\x89PNG...'), not strings.
Moving around in the File: seek() and tell()
The file has a “cursor” indicating the current position (in bytes). When you read, the cursor advances.
tell(): Returns the current cursor position (integer).seek(offset, whence): Moves the cursor.offset: How many bytes to move.whence: Where to start from (0: start of file, 1: current position, 2: end of file).
Note: In text files,
seek()is only partially supported (usually only to the beginningseek(0)or to positions obtained fromtell()). In binary files it is fully supported.
with open("data.bin", "rb") as f:
print(f.read(10)) # Reads the first 10 bytes
print(f.tell()) # Prints 10
f.seek(0) # Go back to the beginning
print(f.read(5)) # Re-reads the first 5 bytes
f.seek(0, 2) # Go to the end of the file
size = f.tell() # Position at the end equals file size!
print(f"The file is {size} bytes")
Practical Exercises
Exercise 1 — Log File Analysis
You have a text file server.log.
- Count how many lines contain the word “ERROR”.
- Create a new file
errors_only.txtcopying only those lines into it.
Exercise 2 — Hidden Message
You have a binary file. You know the secret message starts at byte 50 and ends at byte 100. Write a script that:
- Opens the file in binary mode.
- Moves to byte 50.
- Reads 50 bytes.
- Tries to decode them as text (
data.decode('utf-8')) and prints the result.
EC