Most programs need to work with data that outlives a single run. When a program ends, all variables stored in memory are lost, so permanent storage is required for records such as student marks, employee details, or inventory. File handling is the technique of storing and retrieving data on secondary storage devices like hard disks through Python programs. A file is a named collection of related data stored on persistent media, and Python provides a rich set of built-in functions to create, read, write and modify files.
Python treats a text file as a sequence of characters and a binary file as a sequence of bytes. The file functions are provided through the built-in open() function, which returns a file object supporting methods like read(), readline(), readlines(), write() and writelines(). The close() method flushes the buffer and releases the file. Beginning with Python 3, the with statement manages file objects safely, guaranteeing that the file is closed even when an exception occurs.
This chapter covers opening files in various modes, reading and writing text files line by line, using the os.path module to test file existence, and performing operations on CSV and binary files. File handling is a frequent source of short answer and code-writing questions in the board examination, and it builds directly on the exception handling skills of the previous chapter, since file operations frequently fail when files are missing, locked or inaccessible.
The built-in function open() is used to open a file. It returns a file object, commonly called a handle. The first argument is the file name, and the second argument is the mode. If the file cannot be opened, an IOError or FileNotFoundError is raised.
f = open("student.txt", "w")
f.write("Hello World")
f.close()
The close() method must be called to flush any buffered data to disk and release the file. Failing to close a file can leave data unwritten or the file locked by the operating system.
The mode string tells Python how the file will be used. The default mode is "r" (read text). Common modes are "r" (read), "w" (write, truncating an existing file), "a" (append), "rb" (read binary), "wb" (write binary), "r+" (read and write), "w+" (write and read, truncating) and "a+" (append and read). In binary modes the b character is appended, as in "wb" or "rb".
f = open("data.txt", "a")
f.write("Appending a line\n")
f.close()
With "a" the pointer starts at the end, so new content is added without destroying the existing data.
The with statement automatically closes the file when the block ends, even if an exception is raised inside. This is the recommended, safe way to handle files.
with open("data.txt", "w") as f:
f.write("Automatically closed after this block")
No explicit close() call is needed, and the file is released reliably even on errors.
Python provides several methods for reading text files. The read() method reads the entire file as a single string; readline() reads one line including the newline character; and readlines() returns a list of all lines, each ending with a newline.
with open("student.txt", "r") as f:
data = f.read()
print(data)
The for loop is the most efficient way to process a file line by line, since it reads lazily and does not load the whole file into memory.
with open("student.txt", "r") as f:
for line in f:
print(line, end="")
The end="" suppresses the extra blank line caused by the newline already present in each line.
The read(n) form reads at most n characters (or bytes in binary mode). This is useful when a fixed-size chunk is needed.
with open("data.txt", "r") as f:
first10 = f.read(10)
print(first10)
The file object keeps track of a position called the file pointer. tell() returns the current position in bytes, and seek(offset, whence) moves the pointer. With seek(0) the pointer moves to the start of the file, allowing the file to be re-read.
with open("data.txt", "r") as f:
print("Position:", f.tell())
f.read(5)
print("After read(5):", f.tell())
f.seek(0)
print("After seek(0):", f.tell())
The write() method writes a string to the file and returns the number of characters written. The writelines() method writes a list of strings. Note that writelines() does not add newlines automatically; they must be included in the strings.
lines = ["Line one\n", "Line two\n", "Line three\n"]
with open("output.txt", "w") as f:
f.writelines(lines)
A common practical task is to write multiple records, each on its own line.
with open("students.txt", "w") as f:
for i in range(3):
name = input("Enter name: ")
marks = input("Enter marks: ")
f.write(name + " " + marks + "\n")
Reading the records back line by line and splitting them on whitespace retrieves the stored values.
with open("students.txt", "r") as f:
for line in f:
parts = line.strip().split()
print("Name:", parts[0], "Marks:", parts[1])
The append mode "a" opens the file for adding content at the end. If the file does not exist, append mode creates it. This is ideal for log files and records that grow over time.
with open("log.txt", "a") as f:
f.write("New log entry\n")
Binary files store data as a sequence of bytes. They are handled with modes containing b, and the standard Python module pickle serialises Python objects into binary form. pickle.dump(obj, file) writes an object and pickle.load(file) reads it back.
import pickle
record = {"roll": 1, "name": "Riya", "marks": 95}
with open("record.dat", "wb") as f:
pickle.dump(record, f)
with open("record.dat", "rb") as f:
data = pickle.load(f)
print(data)
A typical examination task is to search for a record inside a binary file.
import pickle
target = int(input("Enter roll number: "))
found = False
with open("record.dat", "rb") as f:
while True:
try:
rec = pickle.load(f)
except EOFError:
break
if rec["roll"] == target:
print(rec["name"], rec["marks"])
found = True
if not found:
print("Record not found")
The EOFError exception marks the end of the file when pickle.load() has no more objects.
The os.path module provides functions to inspect paths and files. os.path.exists(path) checks whether a file or directory exists, and os.path.isfile(path) and os.path.isdir(path) distinguish files from folders. os.remove(filename) deletes a file.
import os
if os.path.exists("data.txt"):
print("File exists")
size = os.path.getsize("data.txt")
print("Size in bytes:", size)
else:
print("File does not exist")
CSV (Comma Separated Values) is a simple text format where each line is a record and fields are separated by commas. The csv module simplifies reading and writing such files.
import csv
with open("marks.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerow(["Name", "Marks"])
writer.writerow(["Aman", 88])
writer.writerow(["Bhavna", 92])
with open("marks.csv", "r") as f:
reader = csv.reader(f)
for row in reader:
print(row)
The newline="" argument prevents extra blank lines between rows when writing.
| Mode | Operation | Pointer Position | Creates File? |
|---|---|---|---|
| r | Read text | Start | No |
| w | Write text (truncate) | Start | Yes |
| a | Append text | End | Yes |
| rb | Read binary | Start | No |
| wb | Write binary (truncate) | Start | Yes |
| r+ | Read and write | Start | No |
| Method | Purpose |
|---|---|
| read() / read(n) | Read whole file / n characters |
| readline() | Read one line |
| readlines() | Read all lines into a list |
| write(str) | Write a string |
| writelines(list) | Write a list of strings |
| tell() | Return current pointer position |
| seek(offset) | Move pointer to offset |
| close() | Close the file |
with statement.w mode truncates the existing file immediately, destroying all old content. Use a to append.r mode raises FileNotFoundError; check os.path.exists() first or use exception handling.writelines() does not add newlines automatically, so lines may run together on one line."r" instead of "rb" corrupts binary data because of text decoding.newline="" is not supplied when writing.w truncates, a appends and r does not create files.File handling connects a Python program to permanent storage, allowing data to survive between runs. Opening files in the correct mode is the first and most critical decision, since the mode determines whether data is read, overwritten, or preserved. Text files are processed with read, readline, readlines, write and writelines, while seek and tell give precise control over the file pointer. Binary files rely on the pickle module for serialisation, and the csv module handles tabular data cleanly. The os.path module provides the utilities to check existence, and the with statement guarantees safe closure. Combined with exception handling, these tools enable robust programs that read, update and search persistent records. In the next chapter, the stack data structure shows how a program can manage a collection of data in a disciplined, last-in-first-out fashion.