2. Python File Handling: 5 Practical Programs

10 min readUpdated September 2, 2026
2. Python File Handling: 5 Practical Programs

Python File Handling: 5 Practical Programs Every Python Developer Should Know

File handling is a fundamental Python skill, but in real projects it goes far beyond simply using open() and read(). A good Python developer should understand how files are opened, how data is read and written, how the file cursor works, how different modes affect existing data, and how to process large files without unnecessarily consuming memory.

This article brings five practical programs together in one place—from beginner-friendly filesystem checks to an experience-level problem involving large files. The examples are based on the concepts covered in the supplied study material, including file existence, line/word/character counting, tell()/seek(), file modes, and multi-file processing.


What You’ll Learn

By the end of this article, you should be able to:

  • Check whether a file exists
  • Read a file efficiently
  • Count lines, words, and characters
  • Understand the file cursor
  • Use tell() and seek()
  • Understand r, w, x, a, r+, w+, and x+
  • Understand when data is overwritten versus appended
  • Process large files without loading everything into memory
  • Answer practical file-handling interview questions

Program 1: Check Whether a File Exists

Problem

Write a Python program to check whether the given file exists or not.

This is a very common requirement in real applications.

For example, before reading:

configuration.json
employees.csv
application.log

we may want to verify that the file actually exists.

The supplied material demonstrates this requirement using os.path.isfile().


Solution

import os
file_path = input("Enter file path: ").strip()
if os.path.isfile(file_path):
print(f"File exists: {file_path}")
else:
print(f"File does not exist: {file_path}")

Example

Suppose the user enters:

employees.txt

Output:

File exists: employees.txt

If the file doesn’t exist:

File does not exist: employees.txt

How Does It Work?

Let’s break it down.

Step 1 — Import os

import os

os provides operating-system-related functionality, including filesystem operations.

Step 2 — Get the file path

file_path = input("Enter file path: ").strip()

The user provides the file name or complete path.

Step 3 — Check the path

os.path.isfile(file_path)

This returns:

True → path exists and refers to a regular file
False → it isn't a regular file at that path

Step 4 — Take action

if os.path.isfile(file_path):

If the result is True, we know we can proceed with file-related processing.


Better Production Approach

Checking existence separately and then opening the file can introduce a time-of-check/time-of-use race condition in concurrent environments.

For simple scripts, the existence check is perfectly reasonable.

For robust application code, you can often simply attempt the operation and handle the exception:

try:
with open("employees.txt", "r", encoding="utf-8") as file:
data = file.read()
print(data)
except FileNotFoundError:
print("File was not found.")

Interview Question

Should I always use os.path.isfile() before open()?

Not necessarily.

A strong answer is:

For a simple validation or user-facing check, isfile() is useful. But when the actual operation is opening the file, attempting the operation and handling FileNotFoundError is often more robust because the filesystem can change between the check and the open.


Program 2: Count Lines, Words, and Characters

Problem

Write a Python program to count the number of lines, words, and characters present in a file.

This is a classic file-processing problem and is useful for understanding how to process a file incrementally. The supplied material uses line iteration, len(), and split() for this problem.


Solution

def count_file_statistics(file_path):
line_count = 0
word_count = 0
character_count = 0
with open(file_path, "r", encoding="utf-8") as file:
for line in file:
line_count += 1
character_count += len(line)
word_count += len(line.split())
print(f"Lines : {line_count}")
print(f"Words : {word_count}")
print(f"Characters : {character_count}")
file_path = input("Enter file path: ").strip()
try:
count_file_statistics(file_path)
except FileNotFoundError:
print("File does not exist.")

Example Input File

Suppose data.txt contains:

Python is powerful
Python is easy to learn
File handling is important

The program might produce:

Lines : 3
Words : 12
Characters : 77

The exact character count depends on spaces and newline characters.


How Does This Program Work?

The important line is:

for line in file:

This means Python reads the file progressively rather than explicitly loading the entire file into a list.

For every line:

line_count += 1

increments the line count.

Then:

character_count += len(line)

counts the characters in that line.

Finally:

word_count += len(line.split())

splits the line into whitespace-separated pieces and counts them.

For example:

line = "Python is powerful"

then:

line.split()

produces approximately:

["Python", "is", "powerful"]

Therefore:

len(line.split())

is:

3

Why Is This Approach Better for Large Files?

Consider a 5 GB log file.

This approach:

data = file.read()

attempts to bring the entire content into memory.

Our approach:

for line in file:

processes the file progressively.

Conceptually:

Large File
│
▼
Read Line
│
▼
Process Line
│
▼
Read Next Line
│
▼
Process Line

So the algorithm remains:

Time → O(n)
Space → O(k)

where:

  • n = total amount of data processed
  • k = amount of data held during processing, roughly bounded by the current line/buffering

This is a very good interview point.


Program 3: tell() and seek() — Rewrite Text at a Specific Position

Now let’s move from basic file processing to understanding how Python tracks the current position inside a file.

The supplied material introduces tell() as a way to obtain the current cursor position and seek() as a way to move it.


Problem

Suppose a file contains:

Hello Python Programming

We want to move the cursor to a specific position and replace part of the existing content.


Solution

file_path = "data.txt"
# Create initial content
with open(file_path, "w", encoding="utf-8") as file:
file.write("Hello Python Programming")
# Read and modify the content
with open(file_path, "r+", encoding="utf-8") as file:
print("Original Content:")
print(file.read())
print("Current Position:", file.tell())
# Move cursor to position 6
file.seek(6)
print("Position After seek():", file.tell())
# Replace "Python" with "World"
file.write("World")
# Move back to beginning
file.seek(0)
print("Modified Content:")
print(file.read())

Output

Original Content:
Hello Python Programming
Current Position: 24
Position After seek(): 6
Modified Content:
Hello World Programming

Understanding the Cursor

Imagine the file as a sequence of positions:

Hello Python Programming
012345678901234567890123
↑
position 6

When you call:

file.seek(6)

the cursor moves to position 6.

Then:

file.write("World")

writes from that position.

So:

Before:
Hello Python Programming
↑
cursor
After writing:
Hello World Programming
↑

What Does tell() Do?

file.tell()

returns the current position.

For example:

with open("data.txt", "r") as file:
print(file.tell())

Initially:

0

After:

file.read(5)

the position advances accordingly.

The source material demonstrates this progression with tell() after successive reads.


What Does seek() Do?

file.seek(position)

moves the cursor.

Example:

file.seek(0)

moves it back to the beginning.

This is extremely useful when you need to:

  • Re-read data
  • Move to a known position
  • Perform controlled read/write operations
  • Work with random-access patterns

Important Interview Question

Can seek() replace arbitrary text of different lengths?

Not in the general “insert” sense.

For example:

Hello Python

If you seek to the middle and write:

AmazingTechnology

you are overwriting bytes/characters from that position, not automatically shifting all subsequent content to make room.

For inserting text while preserving everything afterward, you typically need to create a new representation or rewrite the affected portion.

This distinction is important in experienced-level interviews.


Program 4: Understanding r, w, x, a, r+, w+, and x+

Understanding file modes is one of the most frequently tested Python file-handling topics.

The supplied material covers r, w, a, r+, w+, a+, and x, along with binary variants.

Let’s understand them through one practical program.


File Mode Cheat Sheet

ModeReadWriteExisting FileMissing File
rYesNoRequiredError
wNoYesTruncatesCreates
xNoYesErrorCreates
aNoYesPreservesCreates
r+YesYesRequiredError
w+YesYesTruncatesCreates
x+YesYesErrorCreates

4.1 r — Read

with open("data.txt", "r", encoding="utf-8") as file:
print(file.read())

Use r when:

You only need to read existing data.

If the file doesn’t exist:

FileNotFoundError

4.2 w — Write

with open("data.txt", "w", encoding="utf-8") as file:
file.write("New Content")

Important:

Existing content → DELETED
New content → WRITTEN

If the file doesn’t exist, Python creates it.

Interview trap

If you see:

open("important.txt", "w")

ask yourself:

Do I really want to truncate the existing file?


4.3 x — Exclusive Creation

with open("new_data.txt", "x", encoding="utf-8") as file:
file.write("Initial content")

This is useful when you want to ensure that you’re creating a new file rather than accidentally overwriting an existing one.

If the file already exists:

FileExistsError

4.4 a — Append

with open("application.log", "a", encoding="utf-8") as file:
file.write("Application started\n")

Existing content is preserved.

New data is appended.

Old entry
Old entry
Application started

Use a for things such as:

  • Logs
  • Audit entries
  • Event records
  • Append-only data

4.5 r+ — Read and Write

with open("data.txt", "r+", encoding="utf-8") as file:
content = file.read()
file.seek(0)
file.write("Updated")

Important characteristics:

Must already exist
Can read
Can write
Doesn't automatically truncate

The cursor initially starts at the beginning.


4.6 w+ — Write and Read

with open("data.txt", "w+", encoding="utf-8") as file:
file.write("Hello Python")
file.seek(0)
print(file.read())

The critical point:

w+ → existing content is truncated

Then you can both write and read.


4.7 x+ — Create, Read and Write

with open("new_data.txt", "x+", encoding="utf-8") as file:
file.write("Hello Python")
file.seek(0)
print(file.read())

This combines:

x → exclusive creation
+ → reading + writing

If the file already exists:

FileExistsError

A Simple Way to Remember the Modes

Think about the first character:

r → existing resource, read
w → write from scratch
a → append
x → create exclusively

Then:

+ → additionally allow reading and writing

And:

b → binary mode

So:

rb
wb
ab
r+b
w+b
a+b
xb
x+b

represent binary variants.


Program 5: Experience-Level Problem — Merge Two Large Files Without Loading Them Into Memory

Now let’s move to a problem that tests more than syntax.

Problem

You have two large files:

file1.txt
file2.txt

You need to merge their contents into:

merged.txt

The files may be several gigabytes in size.

Constraint

Do not load the complete files into memory.

This is the kind of question that tests whether you understand streaming, memory complexity, file iteration, and resource management.


Solution

def merge_files(file1, file2, output):
with (
open(file1, "r", encoding="utf-8") as f1,
open(file2, "r", encoding="utf-8") as f2,
open(output, "w", encoding="utf-8") as out
):
while True:
line1 = f1.readline()
line2 = f2.readline()
if not line1 and not line2:
break
if line1:
out.write(line1)
if line2:
out.write(line2)
merge_files(
"file1.txt",
"file2.txt",
"merged.txt"
)
print("Files merged successfully.")

How Does This Work?

The important design decision is:

f1.readline()
f2.readline()

instead of:

data1 = f1.read()
data2 = f2.read()

The program reads only the next line from each input file.

Conceptually:

file1 file2
│ │
▼ ▼
read line read line
│ │
└────────┬────────────┘
▼
output file

Then it repeats:

Read
↓
Write
↓
Discard
↓
Read next
↓
Write

The complete contents never need to exist in memory simultaneously.


Why Is This an Experienced-Level Problem?

Because a beginner may write:

with open("file1.txt") as f1:
data1 = f1.read()
with open("file2.txt") as f2:
data2 = f2.read()
with open("merged.txt", "w") as out:
out.write(data1)
out.write(data2)

It works.

But imagine:

file1 = 8 GB
file2 = 7 GB

You could create enormous memory pressure.

The streaming solution keeps memory usage bounded.


Complexity Analysis

Let:

N = size of file1
M = size of file2

Every byte must be read and written.

Therefore:

Time Complexity = O(N + M)

because the complete contents of both files must be processed.

The additional working memory is approximately:

Space Complexity = O(k)

where k represents the amount of data held at a time, such as the current lines/buffer.

The important principle is:

You cannot reduce the time below O(N + M) if every byte must be examined/copied, but you can dramatically reduce the additional memory required by streaming.


Bonus Interview Challenge

An interviewer might change the problem:

“Now the files are 100 GB each. How would you merge them?”

The answer should immediately be:

Don't use read().
Don't use readlines().
Use streaming/chunk processing.
Use with/context managers.
Process bounded amounts of data.

For binary data, chunk processing is often preferable:

def copy_file(source_path, destination_path):
with open(source_path, "rb") as source:
with open(destination_path, "wb") as destination:
while chunk := source.read(1024 * 1024):
destination.write(chunk)

Here:

1024 * 1024 = 1 MB

is the chosen chunk size.


Important Production Considerations

The code above demonstrates the core algorithm, but production systems may require additional considerations.

1. Encoding

For text:

encoding="utf-8"

makes the expected encoding explicit.

2. Error handling

Real applications should consider:

FileNotFoundError
PermissionError
UnicodeDecodeError
OSError

depending on the operation.

3. Partial output

If a long-running operation fails halfway through, the output file may be incomplete.

For critical workflows, you may need:

temporary file
↓
write successfully
↓
flush/sync as appropriate
↓
atomic rename

4. Concurrency

If multiple processes write to the same file simultaneously, you need to think about synchronization and consistency.

5. File vs Database

If the requirement becomes:

Millions of records
+
Concurrent updates
+
Transactions
+
Complex queries
+
Indexes

then a database is generally a better architectural choice than a plain text file.


One Concept That Connects All Five Programs

All five programs are really teaching one bigger idea:

Treat external storage as a resource with cost and state.

Let’s connect them.

Program 1

os.path.isfile()

asks:

Does this resource exist?

Program 2

for line in file:

asks:

How can I process the resource efficiently?

Program 3

tell()
seek()

asks:

Where am I inside the resource?

Program 4

r / w / x / a / +

asks:

What operations am I allowed to perform, and what happens to existing data?

Program 5

readline()

asks:

How can I process huge resources without exhausting memory?

That’s the progression from basic Python knowledge to production-level thinking.


Interview Revision Table

QuestionKey Answer
How do you check whether a file exists?os.path.isfile() / Path.is_file()
What does r do?Read existing file
What does w do?Write and truncate/create
What does a do?Append/create
What does x do?Exclusive creation
What does + mean?Enable both reading and writing
What does b mean?Binary mode
What does tell() do?Returns current file position
What does seek() do?Moves file position
Why use with open()?Automatic resource cleanup
Why avoid read() for huge files?It can require O(n) memory
How do you process huge files?Stream line-by-line or in chunks
Complexity of processing entire file?Usually O(n) time
Complexity of streaming?O(n) time, O(k) additional space
Is file I/O CPU-bound?Often I/O-bound
When should you prefer a DB?Queries, transactions, indexing, concurrency, structured data