📘 CodingMarble Learn

File Handling in Python: Save Data That Lasts

Variables vanish when a program ends; files keep data on the disk. A text file stores characters in lines, a binary file stores raw bytes (such as pickled Python objects), and a CSV file stores table rows with commas. You open a file with open(path, mode), using an absolute or relative path and a mode such as r, w, a, r+, rb or wb. The with statement closes the file for you. Text files use write, writelines, read, readline and readlines. seek moves the file pointer and tell reports where it is. pickle.dump and pickle.load save and load objects in binary files, letting you search, append and update records. The csv module's writer (writerow, writerows) and reader handle CSV files.

🎬 Step-by-step story

  1. A file is a row of bytes on the disk. A file pointer (the cursor) marks where the next read or write happens.
  2. The mode decides the start: r reads from the start, w wipes the file first, a puts the cursor at the end so new data is added.
  3. read(5) takes 5 characters and moves the cursor 5 places. readline() takes up to the next newline. tell() says where the cursor is; seek(0) jumps back to the start.
  4. pickle.dump turns a Python list or dict into bytes and writes it to a binary file. pickle.load reads it back into the same object.
  5. A CSV file is a table saved as text: one row per line, commas between values. csv.writer writes rows; csv.reader gives each row back as a list.
  6. Your turn: move the seek slider and pick how many characters to read. Watch tell() and the text you get.

Tip: drag the 3D scene to turn it. Use two fingers to zoom.

🤔 Common doubts, cleared

Where does the data go after the program ends?

Into the file on the disk. It stays there even after power off, unlike variables in RAM.

I opened my file in 'w' and everything was gone. Why?

'w' always wipes the file first. To add to it, use 'a', which puts the cursor at the end.

Why did my second read() return an empty string?

The first read() moved the cursor to the end. Use f.seek(0) to go back to the start.

What is the difference between read(), readline() and readlines()?

read() gives the rest of the file as one string, readline() gives one line, readlines() gives a list of all lines.

Why can't I see my pickled data in Notepad?

pickle stores bytes, not letters. Only pickle.load can turn them back into the object.

Why are the numbers from csv.reader strings?

A CSV file is plain text, so every value comes back as text. Convert with int() or float().

Why files? Text, binary and CSV files

Data in variables lives in RAM and is lost when the program ends. A file stores data on disk permanently.

Absolute and relative paths

A path tells Python where the file is.

In Windows paths, write r'C:\School\marks.txt' (raw string) or use double backslashes, because \n or \t inside a path would be read as special characters.

Opening and closing a file: open modes and with

f = open('marks.txt', 'r') returns a file object (file handle). Always f.close() when done; closing saves any data still waiting in the buffer.

ModeMeaningIf file missingCursor starts
rread only (default)FileNotFoundErrorstart
wwrite only, wipes old datacreates itstart
aappend (add at end)creates itend
r+read and writeerrorstart
w+write and read, wipescreates itstart
a+append and readcreates itend

Add b for binary files: rb, wb, ab, rb+, wb+, ab+.

The with statement

with open('marks.txt', 'r') as f:
    data = f.read()
# the file is closed here automatically

with closes the file by itself when the block ends, even if an exception occurs.

Writing to a text file: write and writelines

with open('poem.txt', 'w') as f:
    f.write('Roses are red\n')
    f.writelines(['Sky is blue\n', 'Python is fun\n'])

To add without wiping, open in 'a' mode.

Reading a text file: read, readline, readlines

# count lines that start with 'T'
c = 0
with open('poem.txt') as f:
    for line in f:
        if line.startswith('T'):
            c += 1
print(c)

Use line.strip() to remove the trailing newline, and line.split() to break a line into words.

seek() and tell(): moving the file pointer

The file pointer is the position (in bytes from the start) where the next read or write happens.

with open('poem.txt') as f:
    print(f.read(5))   # 'Roses'
    print(f.tell())    # 5
    f.seek(0)
    print(f.read(3))   # 'Ros'

Binary files with pickle: dump and load

Pickling (serialisation) turns a Python object into a stream of bytes. Unpickling turns bytes back into the object.

import pickle
rec = {'roll': 1, 'name': 'Asha', 'marks': 92}
with open('stu.dat', 'wb') as f:
    pickle.dump(rec, f)

with open('stu.dat', 'rb') as f:
    r = pickle.load(f)
print(r['name'])   # Asha

Each dump writes one object. To read all objects, call load in a loop until EOFError:

with open('stu.dat', 'rb') as f:
    try:
        while True:
            print(pickle.load(f))
    except EOFError:
        pass

Search, append and update in a binary file

Append

Open in 'ab' and pickle.dump the new record. Old records stay.

Search

Open in 'rb', load records one by one, and check a field: if r['roll'] == 5: print(r); found = True. After the loop, print 'Not found' if found is still False.

Update

Method 1 (simple): load all records into a list, change the matching one, then open the file in 'wb' and dump all again.

recs = []
with open('stu.dat', 'rb') as f:
    try:
        while True:
            recs.append(pickle.load(f))
    except EOFError:
        pass
for r in recs:
    if r['roll'] == 2:
        r['marks'] = 80
with open('stu.dat', 'wb') as f:
    for r in recs:
        pickle.dump(r, f)

Method 2 (in place): open in 'rb+', note pos = f.tell() before each load, and when the record matches, f.seek(pos) and dump the changed record (works when the new record has the same size in bytes).

CSV files: csv.writer and csv.reader

import csv
with open('class.csv', 'w', newline='') as f:
    w = csv.writer(f)
    w.writerow(['Roll', 'Name', 'Marks'])
    w.writerows([[1, 'Asha', 92], [2, 'Ravi', 75]])

with open('class.csv', 'r') as f:
    for row in csv.reader(f):
        print(row)       # ['1', 'Asha', '92'] …

Try it: a mini diary

Write a program that asks for one line and appends it to diary.txt using mode 'a'. Run it three times. Now open the file in mode 'w' once and write one line. Open diary.txt in Notepad after each run. You will see with your own eyes that 'w' wiped everything. Then use the free-play step in the 3D to predict what seek and read(n) return.

Key formulas and definitions

Worked examples

1. Which mode would you use: (a) add new rows to a log without losing old ones (b) make a new report file every time (c) read a saved binary record?

(a) 'a' (append; cursor at end). (b) 'w' (creates or wipes). (c) 'rb' (read binary).

2. poem.txt holds 'Roses are red\nSky is blue\n'. What do f.readline(), then f.read(3), then f.tell() give?

readline() → 'Roses are red\n' (14 characters: 13 letters/spaces + newline). read(3) → 'Sky'. tell() → 14 + 3 = 17 (on a system where newline is 1 byte).

3. Write a function that counts the words in story.txt.

def count_words(): with open('story.txt') as f: return len(f.read().split()) print(count_words())

4. Write a function that displays lines of notes.txt that are shorter than 20 characters.

def short_lines(): with open('notes.txt') as f: for line in f: if len(line.rstrip('\n')) < 20: print(line, end='')

5. A binary file book.dat has records [book_no, title, price]. Write a function to add one record.

import pickle def add_book(): rec = [int(input('No: ')), input('Title: '), float(input('Price: '))] with open('book.dat', 'ab') as f: pickle.dump(rec, f)

6. Write a function that shows all books costing more than 300 from book.dat and says if none were found.

def costly(): found = False with open('book.dat', 'rb') as f: try: while True: r = pickle.load(f) if r[2] > 300: print(r); found = True except EOFError: pass if not found: print('No such book')

7. Update the price of book number 3 to 450 in book.dat.

Load all records into a list (loop until EOFError), set r[2] = 450 where r[0] == 3, then reopen with 'wb' and dump every record again. Mode 'wb' is needed because we rewrite the whole file.

8. Write two functions: add rows [id, name, phone] to contacts.csv, and print the names of all contacts.

import csv def add(rows): with open('contacts.csv', 'a', newline='') as f: csv.writer(f).writerows(rows) def names(): with open('contacts.csv') as f: for row in csv.reader(f): print(row[1])

Common mistakes

Practice quiz

1. Which mode deletes the old contents of a file?
2. readlines() returns:
3. Which function tells the current position of the file pointer?
4. pickle.load() raises which exception at the end of the file?
5. Which method writes many rows at once to a CSV file?

Practice: answer these yourself

Type or choose your answer, then press Check. Use a hint if you are stuck; the full solution appears after you answer.

Frequently asked questions

What are the types of files in Python class 12?

Text files (readable characters), binary files (raw bytes, used with pickle) and CSV files (table rows separated by commas).

What is the difference between seek() and tell()?

tell() returns where the file pointer is now. seek() moves the file pointer to a new position.

What is the difference between write() and writelines()?

write() writes one string. writelines() writes every string from a list. Neither adds newlines by itself.

Where this is taught

RomaniaClasa a IX-aStoring data and organising code in a programming language
RomaniaClasa a IX-aStoring data and organising code in a programming language
RomaniaClasa a IX-aStoring data and organising code in a programming language
RomaniaClasa a X-aStructured data
CBSE (India)Class 12Computational Thinking and Programming - 2
USA (Common Core, NGSS, AP)Grade 11Data Collections
South Korea고등학교 2학년Algorithms and programming
South Korea고등학교 3학년Programming
Russia10 классAlgorithms and programming

Learn first

Learn next

Related lessons

All Computer Science lessons