Popular Searches
Popular Course Categories
Popular Courses

Reading and Writing Text Files

Reading and Writing Text Files

File Handling and Data Serialization

Reading and Writing Text Files in Python

Course: Python Training

Topic: Reading and Writing Text Files

Course Link: Python Training Course – JustAcademy

Demo Link: Register for a Course Demo

Website: JustAcademy


1. Introduction to Reading and Writing Text Files

File handling is an important Python programming concept that allows applications to store, retrieve, update, and manage information on a computer. Variables store data temporarily while a program runs, whereas text files allow information to remain available after the program finishes.

Python provides built-in functions and methods for working with text files. You can use these features to store user information, maintain application logs, save reports, read configuration settings, and process textual datasets.

A text file stores readable characters, such as letters, numbers, punctuation marks, and newline characters. Common examples include .txt, .csv, and many configuration files.

Why Is File Handling Important?

  • Permanent storage: Save information beyond the current program execution.
  • Data retrieval: Read previously stored information whenever required.
  • Report generation: Generate summaries, logs, and output files automatically.
  • Data processing: Read text-based datasets and process them programmatically.
  • Application development: Store preferences, records, and other simple application data.

Example of a Text File

Consider a file named student.txt containing the following information:

Name: Rahul
Course: Python Programming
Duration: 3 Months
Status: Enrolled

A Python program can read this information, display it, search for particular details, or write updated information into another file.


2. Understanding the open() Function

The built-in open() function is used to access a file. It returns a file object through which Python can read or write data.

Syntax

open(file, mode='r', encoding=None)
Parameter Description
file The filename or path of the file to open.
mode Specifies whether the file is opened for reading, writing, appending, or another operation.
encoding Specifies how text characters are decoded when reading and encoded when writing.

Opening a File for Reading

file = open("student.txt", "r", encoding="utf-8")
content = file.read()
print(content)
file.close()

In this example, Python opens student.txt in read mode, reads its complete contents, prints the text, and closes the file. The file must exist when using read mode; otherwise, Python raises a FileNotFoundError.

Although this example demonstrates the basic process, using a with statement is generally safer because it closes the file automatically.


3. Understanding File Opening Modes

File modes determine how Python interacts with a file. Choosing the correct mode is essential because some modes can erase existing content.

Mode Purpose Behavior
r Read Opens an existing file for reading. Fails if the file does not exist.
w Write Creates a file if necessary or truncates an existing file.
a Append Adds new content at the end of a file or creates it if missing.
x Exclusive creation Creates a new file but fails if the file already exists.
r+ Read and write Opens an existing file for reading and writing without initially truncating it.
w+ Write and read Creates a file or truncates an existing file, allowing both operations.
a+ Append and read Allows reading and appending; writes are directed to the end of the file.
rt Read text Opens a file in text-reading mode. This is equivalent to r.

Example: Write Mode

with open("example.txt", "w", encoding="utf-8") as file:
    file.write("Welcome to Python file handling.")

print("File written successfully.")

If example.txt already contains information, write mode removes the existing content before writing the new text. Use this mode carefully when the original data must be preserved.

Example: Append Mode

with open("example.txt", "a", encoding="utf-8") as file:
    file.write("\nLearning file handling is useful.")

print("New content appended.")

Append mode preserves the existing content and adds the new text at the end. The newline character \n separates the new sentence from the previous content when necessary.


4. Reading an Entire Text File with read()

The read() method retrieves file content and returns it as a string in text mode. It is useful when the entire file is small enough to fit comfortably in memory.

Syntax

file.read(size=-1)

The optional size parameter specifies the maximum number of characters to read in text mode. If omitted, the method reads the remaining content.

Example

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

print(content)

Suppose the file contains:

Hello, Python!
This is a text file.
File handling is easy to learn.

The program displays all three lines because read() retrieves the complete remaining content.

Reading a Limited Number of Characters

with open("message.txt", "r", encoding="utf-8") as file:
    first_part = file.read(5)

print(first_part)

Output:

Hello

After this operation, the file's current position is immediately after the five characters read. A subsequent call to read() retrieves the remaining content rather than starting again from the beginning.

When Should You Use read()?

  • When reading short text files.
  • When the entire content must be searched or transformed as a single string.
  • When loading small configuration files or templates.
  • Avoid reading very large files completely into memory unless the application can safely handle their size.

5. Reading One Line with readline()

The readline() method reads one line from a file at a time. It normally includes the newline character at the end of the returned string if one exists in the file.

Example

with open("students.txt", "r", encoding="utf-8") as file:
    first_line = file.readline()
    second_line = file.readline()

print(first_line, end="")
print(second_line, end="")

Suppose the file contains:

Rahul
Priya
Amit

Output:

Rahul
Priya

The first call reads the first line, and the second call reads the next line. The file position advances after each operation.

Reading Lines Until the End of a File

with open("students.txt", "r", encoding="utf-8") as file:
    while True:
        line = file.readline()

        if line == "":
            break

        print(line, end="")

In text mode, an empty string returned by readline() indicates the end of the file. A blank line inside the file is different: it usually returns a string containing a newline character.


6. Reading All Lines with readlines()

The readlines() method reads the remaining lines and returns them as a list of strings. Each string usually retains its line-ending character when one exists.

Example

with open("students.txt", "r", encoding="utf-8") as file:
    lines = file.readlines()

print(lines)

Example output:

['Rahul\n', 'Priya\n', 'Amit']

The exact representation depends on whether the final line ends with a newline character.

Removing Newline Characters

with open("students.txt", "r", encoding="utf-8") as file:
    lines = file.readlines()

clean_lines = [line.rstrip("\n") for line in lines]

print(clean_lines)

Output:

['Rahul', 'Priya', 'Amit']

Alternatively, line.strip() removes whitespace from both ends, which may also remove meaningful leading or trailing spaces. Choose the method based on your data requirements.

When Should You Use readlines()?

  • When the file is small or moderate in size.
  • When you need a list of lines for indexing or repeated processing.
  • When you need to count, sort, or filter lines after loading them.
  • For very large files, prefer iterating over the file directly to reduce memory usage.

7. Iterating Directly Over a File

A file object is iterable. This means Python can read it one line at a time using a for loop. This approach is often the most practical way to process large text files because it avoids loading every line into a list at once.

Example

with open("students.txt", "r", encoding="utf-8") as file:
    for line in file:
        print(line, end="")

Processing Only Matching Lines

with open("application.log", "r", encoding="utf-8") as file:
    for line in file:
        if "ERROR" in line:
            print(line, end="")

This program prints only the lines containing the word ERROR. It is useful when analyzing application logs, server output, and diagnostic reports.

Comparing Reading Methods

Method Return Type Best Use
read() String Reading all content or a specified number of characters.
readline() String Reading one line at a time manually.
readlines() List of strings Loading all lines into a list.
for line in file One line per iteration Memory-efficient sequential processing.

8. Writing Text to a File with write()

The write() method writes a string to an open text file. It returns the number of characters written, but it does not automatically add a newline character.

Syntax

file.write(string)

Example: Writing a Single Line

with open("output.txt", "w", encoding="utf-8") as file:
    file.write("Python is a versatile programming language.")

print("Text saved successfully.")

The program creates output.txt if it does not exist. If it already exists, its previous content is truncated.

Writing Multiple Lines

with open("output.txt", "w", encoding="utf-8") as file:
    file.write("Introduction to Python\n")
    file.write("Reading text files\n")
    file.write("Writing text files\n")

print("Multiple lines written.")

The \n character represents a line break in a Python string. Text-mode file handling normally translates line endings appropriately for the operating system.

Writing Variables to a File

student_name = "Ananya"
course_name = "Python Training"
score = 92

with open("student_report.txt", "w", encoding="utf-8") as file:
    file.write(f"Student: {student_name}\n")
    file.write(f"Course: {course_name}\n")
    file.write(f"Score: {score}\n")

Formatted strings, also known as f-strings, allow variables and expressions to be inserted into text before the result is written to the file.


9. Writing Multiple Strings with writelines()

The writelines() method writes an iterable of strings to a file. Unlike print(), it does not automatically insert newline characters between the strings.

Example

topics = [
    "Variables and data types\n",
    "Conditional statements\n",
    "Loops and functions\n",
    "File handling\n"
]

with open("topics.txt", "w", encoding="utf-8") as file:
    file.writelines(topics)

The file contains one topic per line because every string already includes \n.

Common Mistake

topics = ["Python", "Java", "JavaScript"]

with open("languages.txt", "w", encoding="utf-8") as file:
    file.writelines(topics)

The resulting file contains PythonJavaJavaScript because the strings have no separators.

Corrected Example

topics = ["Python", "Java", "JavaScript"]

with open("languages.txt", "w", encoding="utf-8") as file:
    file.writelines(topic + "\n" for topic in topics)

Alternatively, use "\n".join(topics) with write() when you want to join strings using newline characters.


10. Appending Content Without Deleting Existing Data

Append mode is useful when an application needs to add new information while preserving previously stored text. Common examples include activity logs, attendance records, and simple history files.

Example: Adding Log Entries

from datetime import datetime

message = "User logged in successfully"

with open("activity.log", "a", encoding="utf-8") as file:
    file.write(f"{datetime.now():%Y-%m-%d %H:%M:%S} - {message}\n")

print("Activity recorded.")

Every execution adds a new timestamped entry to the end of the file. The exact timestamp depends on the computer's local date and time settings.

Difference Between Write and Append

Feature Write Mode (w) Append Mode (a)
Creates a missing file Yes Yes
Preserves existing content No Yes
Typical purpose Creating or replacing a report Adding new entries or log messages
Data-loss risk High if existing content is needed Lower for existing content, but still requires care

11. Using the with Statement to Manage Files

The with statement uses a context manager to ensure that the file is properly closed when execution leaves the block. This also applies when an exception occurs during the operation.

Recommended Approach

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

# The file is closed after the with block.

Opening a File Without with

file = open("notes.txt", "r", encoding="utf-8")

try:
    content = file.read()
    print(content)
finally:
    file.close()

The second example uses try and finally to guarantee cleanup. The with approach is generally shorter and easier to maintain.

Why File Closing Matters

  • Releases operating-system resources associated with the open file.
  • Ensures buffered output is flushed and handled appropriately.
  • Reduces the risk of leaving files open after errors.
  • Makes file-handling code easier to read and maintain.

12. Specifying Character Encoding

Character encoding defines how text characters are represented as bytes in a file. UTF-8 is a widely used encoding that supports English text, many international scripts, and a broad range of symbols.

Writing Unicode Text

message = "Welcome to Python — नमस्ते!"

with open("unicode_notes.txt", "w", encoding="utf-8") as file:
    file.write(message)

Reading Unicode Text

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

print(content)

Specifying the encoding explicitly helps make file behavior consistent across different systems. If a file was created using another encoding, opening it as UTF-8 may raise a UnicodeDecodeError or produce incorrect text if the data happens to decode without an error.

Best Practices for Encoding

  • Use encoding="utf-8" for text files you control unless another format is required.
  • Use the same appropriate encoding when writing and reading a file.
  • Do not assume every existing file uses UTF-8; check its source or documented format.
  • Use binary mode for non-text content such as images, audio, and executable files.

13. Working with File Paths

A file path identifies where a file is located. A filename such as notes.txt is a relative path, meaning it is resolved from the program's current working directory. An absolute path identifies a location more explicitly.

Relative Path Example

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

Using pathlib for Path Management

from pathlib import Path

file_path = Path("data") / "notes.txt"

with file_path.open("r", encoding="utf-8") as file:
    content = file.read()

print(content)

The pathlib module offers an object-oriented way to construct and manage paths across operating systems. The example expects a data directory containing notes.txt.

Creating Parent Directories Before Writing

from pathlib import Path

file_path = Path("reports") / "summary.txt"
file_path.parent.mkdir(parents=True, exist_ok=True)

with file_path.open("w", encoding="utf-8") as file:
    file.write("Monthly report generated successfully.")

The directory is created if it does not already exist. The exist_ok=True argument prevents an error when the directory already exists.


14. Checking Whether a File Exists

Before reading a file, a program may need to check whether the expected path exists. The pathlib.Path class provides the exists() method.

Example

from pathlib import Path

file_path = Path("student.txt")

if file_path.exists() and file_path.is_file():
    with file_path.open("r", encoding="utf-8") as file:
        print(file.read())
else:
    print("The requested file does not exist.")

exists() checks whether the path exists, while is_file() checks whether it refers to a file. Checking first can improve user feedback, but the file could still change between the check and the attempted open. Handle file errors even when performing these checks.


15. Handling File Exceptions

File operations can fail because a file is missing, access is denied, a directory is used incorrectly, or the file contains text that cannot be decoded using the selected encoding. Exception handling allows a program to respond appropriately instead of terminating unexpectedly.

Exception Possible Cause Typical Response
FileNotFoundError The requested file or a path component is missing. Check the path or explain that the file is unavailable.
PermissionError The process lacks the required permissions. Check file permissions and access settings.
IsADirectoryError A directory was opened as though it were a file. Provide the path to a file instead.
UnicodeDecodeError Text bytes cannot be decoded using the selected encoding. Verify the file's actual encoding.
OSError An operating-system-level file operation failed. Inspect the underlying error and environment.

Example: Safe File Reading

from pathlib import Path

file_path = Path("student.txt")

try:
    with file_path.open("r", encoding="utf-8") as file:
        content = file.read()
        print(content)
except FileNotFoundError:
    print("Error: The requested file was not found.")
except PermissionError:
    print("Error: You do not have permission to read this file.")
except UnicodeDecodeError:
    print("Error: The file could not be decoded as UTF-8.")
except OSError as error:
    print(f"File operation failed: {error}")

Catch specific exceptions when you can handle them meaningfully. A broader OSError handler can be used after more specific handlers for other operating-system-related file errors.


16. File Positions: tell() and seek()

Python maintains a current position within an open file. Reading and writing operations may advance that position. The tell() method reports the current position, while seek() moves to a different position supported by the file object.

Example

with open("message.txt", "r", encoding="utf-8") as file:
    first_part = file.read(5)
    print("First part:", first_part)
    print("Current position:", file.tell())

    file.seek(0)
    complete_content = file.read()

    print("Complete content:", complete_content)

Here, seek(0) moves back to the beginning of the file so the content can be read again.

Important Considerations

  • Use seek(0) to return to the start of a file.
  • The position returned by tell() in text mode should be treated as an opaque position marker rather than assumed to be a simple character count.
  • Text-mode seeking has restrictions compared with binary-mode seeking.
  • After reaching the end of a file, another read() normally returns an empty string unless the position is changed.

17. Building a Simple Text File Application

This practical example creates a small student-notes application. It writes student information to a text file and then reads the saved information back.

Complete Program

from pathlib import Path

file_path = Path("student_records.txt")

def save_student(name, course, score):
    record = (
        f"Name: {name}\n"
        f"Course: {course}\n"
        f"Score: {score}\n"
        f"{'-' * 25}\n"
    )

    with file_path.open("a", encoding="utf-8") as file:
        file.write(record)

def display_students():
    try:
        with file_path.open("r", encoding="utf-8") as file:
            content = file.read()

        if content:
            print(content)
        else:
            print("No student records found.")

    except FileNotFoundError:
        print("No records file exists yet.")

save_student("Rahul", "Python", 88)
save_student("Priya", "Data Analytics", 94)

print("Saved student records:")
display_students()

How the Program Works

  1. Import: The Path class helps manage the file path.
  2. Define the path: The records are stored in student_records.txt in the current working directory.
  3. Create a save function: save_student() formats a record using f-strings.
  4. Append records: Append mode preserves records already stored in the file.
  5. Read saved data: display_students() opens the file in read mode.
  6. Handle missing data: If the file does not exist, the function displays a helpful message.

This program is suitable as a beginner exercise. A production application may need a structured data format, input validation, stronger error handling, and a database if the records become complex.


18. Practical Use Cases of Text File Handling

Use Case 1: Saving User Notes

user_note = input("Enter your note: ")

with open("my_notes.txt", "a", encoding="utf-8") as file:
    file.write(user_note + "\n")

print("Note saved.")

This program appends the user's note to a file so it remains available after the program ends.

Use Case 2: Counting Lines in a File

with open("article.txt", "r", encoding="utf-8") as file:
    line_count = sum(1 for line in file)

print("Total lines:", line_count)

This approach counts lines without storing the complete file in a list.

Use Case 3: Counting Words

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

words = content.split()
print("Total words:", len(words))

The split() method separates the text into whitespace-delimited pieces. This is a simple word-counting approach, not a complete linguistic tokenizer.

Use Case 4: Searching for a Word

search_word = "Python"

with open("article.txt", "r", encoding="utf-8") as file:
    for line_number, line in enumerate(file, start=1):
        if search_word.casefold() in line.casefold():
            print(f"Found on line {line_number}: {line}", end="")

The casefold() method supports case-insensitive comparisons. The example searches for a substring, so it also matches the word inside a longer word. Exact word matching requires additional logic.


19. Common Mistakes and Troubleshooting

Problem Why It Happens Solution
FileNotFoundError The file is not in the expected location. Check the current working directory and file path.
Existing data disappears The file was opened with w. Use a to append when existing content must remain.
All text appears on one line Newline characters were not added. Use \n or join strings with a newline separator.
Only part of the file is returned A previous read moved the file position. Use seek(0) when appropriate or reopen the file.
File remains open The file was opened without proper cleanup. Use a with statement.
Unexpected characters appear The wrong encoding was used. Determine the file's encoding and specify it correctly.
Numbers cannot be written directly write() expects a string in text mode. Convert the value with str() or use an f-string.
Large files consume too much memory The complete file was loaded with read() or readlines(). Iterate over the file line by line.

Example: Correcting a Data Type Error

Incorrect approach:

score = 95

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

This raises a TypeError because score is an integer rather than a string.

Correct approach:

score = 95

with open("score.txt", "w", encoding="utf-8") as file:
    file.write(str(score))

An f-string also works: file.write(f"{score}").


20. Best Practices for Reading and Writing Text Files

  • Prefer with open(...) or Path.open(...) to manage file resources safely.
  • Specify the file encoding explicitly, usually encoding="utf-8" for files you control.
  • Choose the correct mode before opening a file. Remember that w truncates existing content.
  • Use append mode when new records must be added without replacing existing data.
  • Use direct file iteration for large text files.
  • Handle expected exceptions, including missing files and permission errors.
  • Use pathlib to construct file paths in a clear, cross-platform way.
  • Validate input before writing user-provided information to a file.
  • Do not store passwords, secret keys, or other sensitive information in plain-text files without appropriate security controls.
  • Use a structured format such as JSON or CSV when the data has a defined structure, and consider a database for complex records or concurrent access.
  • Be careful when writing to important files. Consider backups or writing to a temporary file before replacing a valuable file.
  • Remember that write() and writelines() do not automatically add line breaks.

21. Practice Exercises

Beginner Exercises

  1. Create a text file named welcome.txt and write a welcome message to it.
  2. Read the complete contents of a text file and display them on the screen.
  3. Read a file one line at a time using readline().
  4. Write five programming languages to a file, with each language on a separate line.
  5. Append your name and today's study topic to an existing text file.

Intermediate Exercises

  1. Write a program that counts the number of lines in a text file.
  2. Write a program that counts words and characters in a text file.
  3. Search a file for a user-provided keyword and display matching line numbers.
  4. Build a simple activity logger that appends messages with timestamps.
  5. Handle a missing file and display a meaningful error message instead of terminating unexpectedly.

Advanced Mini-Project: Personal Notes Manager

Create a command-line application that lets users add, view, and search notes stored in a text file.

Requirements:

  • Display a menu with options to add, view, search, and exit.
  • Append each new note instead of overwriting existing notes.
  • Read notes efficiently when displaying or searching them.
  • Handle missing files and invalid menu selections.
  • Use UTF-8 encoding and context managers consistently.
  • Separate the program into functions such as add_note(), view_notes(), and search_notes().

22. Interview Questions and Answers

Q1. What is file handling in Python?

Answer: File handling is the process of opening, reading, writing, appending, and managing files using Python. It allows programs to store and retrieve information beyond a single execution.

Q2. What does the open() function do?

Answer: The open() function opens a file and returns a file object that provides methods for reading, writing, and other file operations.

Q3. What is the difference between read() and readline()?

Answer: read() reads the remaining content or a specified number of characters, whereas readline() reads one line at a time.

Q4. What is the difference between readlines() and iterating over a file?

Answer: readlines() returns all remaining lines as a list, potentially using substantial memory. Iterating over a file processes one line at a time and is generally more memory-efficient for large files.

Q5. What is the difference between write mode and append mode?

Answer: Write mode (w) creates or truncates a file before writing. Append mode (a) preserves existing content and adds new content at the end.

Q6. Why should you use a with statement when opening files?

Answer: A with statement ensures the file is closed when the block ends, including when an exception occurs.

Q7. Does write() automatically add a newline?

Answer: No. Add \n explicitly when a line break is required.

Q8. What is encoding in file handling?

Answer: Encoding defines how characters are represented as bytes. Using an explicit encoding such as UTF-8 helps ensure consistent text handling across systems.

Q9. What happens when a file is opened in read mode but does not exist?

Answer: Python raises a FileNotFoundError. The program can handle this exception or verify the path while still accounting for possible file-system changes.

Q10. How can you read a large text file efficiently?

Answer: Iterate directly over the file using a for loop. This processes lines sequentially without loading the entire file into memory.

Q11. What is the purpose of seek()?

Answer: The seek() method changes the current file position. For example, seek(0) moves to the beginning when supported by the file object.

Q12. Can write() write an integer directly to a text file?

Answer: No. Convert the integer to a string using str() or an f-string before passing it to write().

Q13. What is the purpose of the x mode?

Answer: The x mode creates a new file and raises FileExistsError if the specified file already exists. It is useful when overwriting an existing file must be avoided.

Q14. How can Python handle errors during file operations?

Answer: Use try and except blocks to handle expected exceptions such as FileNotFoundError, PermissionError, and UnicodeDecodeError.

Q15. When should you use a database instead of a text file?

Answer: A database is generally more suitable when data requires structured queries, relationships, concurrent access, transaction support, or efficient management of large and frequently updated records.


23. Quick Revision Checklist

  • Understand why text files are used for persistent storage.
  • Know how to open files with open().
  • Understand the differences between r, w, a, and x modes.
  • Practice reading content using read(), readline(), and readlines().
  • Use file iteration to process large files efficiently.
  • Write strings with write() and multiple strings with writelines().
  • Remember to add newline characters when required.
  • Use with statements for automatic resource cleanup.
  • Specify an appropriate text encoding.
  • Understand relative paths, absolute paths, and basic pathlib usage.
  • Handle common file-related exceptions.
  • Know when a text file is sufficient and when structured storage is more appropriate.

24. Conclusion

Reading and writing text files is a fundamental Python skill that enables programs to save information, process existing content, generate reports, and maintain simple records. The main operations include opening files with the correct mode, reading content with methods such as read() and readline(), writing strings with write(), and appending new information without replacing existing content.

For reliable code, use context managers, specify the correct encoding, choose file paths carefully, and handle expected exceptions. Practicing these techniques through small applications such as a notes manager or activity logger will build a strong foundation for more advanced Python tasks, including configuration management, data processing, and application development.

Continue learning: Explore the Python Training Course at JustAcademy, visit the course demo registration page, or browse the JustAcademy website.

whatsapp