LambdaLabTM
Computer Science · Class 12 · Text Files
Text filesclose()⏱️ 11 min read

Closing a Text File

Every book says “always close your files”, and every student ignores it, because a program that forgets usually works anyway. Here is the reason it matters — and it is not manners. It is that the words you wrote are not in the file yet.

1close() does two jobs

f.close() takes no arguments and gives nothing back. It ends the connection the handle stood for, and on the way out it does two things:

1 · It empties the buffer onto the disk

Writing to a disk is slow, so Python does not do it a letter at a time. write() puts the characters in a buffer in RAM, and the buffer is emptied onto the disk later — at the latest, when the file is closed.

2 · It hands the file back

The operating system lets a program hold only so many files open at once, and on Windows an open file can be locked against other programs. close() releases both.

2The buffer, made visible

This program writes to a file and then — before closing it — opens the same file again through a second handle and reads it. That second handle is looking at the disk:

the_buffer.py
f = open('draft.txt', 'w')
f.write('Half a line')

check = open('draft.txt', 'r')
print('Before close, the file holds:', repr(check.read()))
check.close()

f.close()

check = open('draft.txt', 'r')
print('After close, the file holds:', repr(check.read()))
check.close()
Output
Before close, the file holds: ''
After close, the file holds: 'Half a line'
🔒 Where the writing actually is

Step through the program. Watch the disk — it does not change until the last line.

buffer · in RAM
(empty)
draft.txt · on the disk
(empty)
another handle reading the file right now
check.read() → ''

The file exists and is empty. 'w' emptied it on the way in.

write() does not write to the disk
Read those two lines again. The write() had already run, and the file on the disk was still empty. The characters were sitting in RAM. close() is what put them in the file — which is why a program that skips it can leave a file with nothing in it.

There is a way to empty the buffer without closing the file: flush(). It is rarely needed, but it proves what the buffer is.

flushing.py
f = open('draft.txt', 'w')
f.write('Half a line')
f.flush()

check = open('draft.txt', 'r')
print('After flush, the file holds:', repr(check.read()))
check.close()

f.close()
Output
After flush, the file holds: 'Half a line'

3A closed handle still exists

close() does not delete the variable. f is still there, still a file object, and f.closed is now True. What it can no longer do is touch the file:

too_late.py
f = open('notes.txt', 'r')
f.close()
print(f.read())
Output
Traceback (most recent call last):
  File "too_late.py", line 3, in <module>
    print(f.read())
          ^^^^^^^^
ValueError: I/O operation on closed file.
A closed file is a common exam trap
ValueError: I/O operation on closed file. means the program closed the file and then tried to use it — usually because close() was written inside a loop that then went round again. Closing twice, though, is harmless: a second close() on an already-closed file does nothing at all.

4What actually goes wrong if you forget

The file ends up empty, or half written

The buffer never reached the disk. This is the one that costs real work, and it happens exactly when the program crashed — which is when you most wanted the data.

The file stays locked

On Windows another program — Excel, Notepad, your own program's next run — may be refused access while your handle is open.

Open handles pile up

A loop that opens a thousand files and closes none will run out. The operating system caps how many one program may hold.

The board takes the marks off

A file-handling answer without close() (or a with block) is not a complete program, and it is marked as such.

So why does forgetting usually work?
When a program ends normally, Python tidies up after it and the files get closed anyway. That is luck, not a rule — it does not save you when the program crashes, and it does not save you in the seconds before the program ends, which is where the empty file above came from.

5The problem with writing close() at the end

Look at where close() sits in this program. It is the last line — so if anything above it raises an exception, it never runs:

never_reached.py
try:
    f = open('notes.txt', 'r')
    print('the file is open')
    print(10 / 0)
    f.close()
except ZeroDivisionError:
    print('The program crashed before close() ran.')

print('closed?', f.closed)
Output
the file is open
The program crashed before close() ran.
closed? False

The fix you already know is finally, from the Exception Handling chapter. finally runs whatever happens, so the file is closed either way:

finally_closes.py
f = open('notes.txt', 'r')
try:
    print('the file is open')
    print(10 / 0)
except ZeroDivisionError:
    print('Something went wrong.')
finally:
    f.close()
    print('closed?', f.closed)
Output
the file is open
Something went wrong.
closed? True
Key Takeaway
That is five lines of scaffolding around two lines of work. Python has a shorter way of saying exactly the same thing, and it is the next lesson: with.

6Try it

Delete the f.close() line below and run it. The 💾 saved.txt pill above the output tells you what the file really holds.

closing.py

7Recap

f.close()

No arguments, no answer. It ends the connection the handle stood for.

It empties the buffer

write() puts characters in RAM. Until they are flushed, the file on the disk does not have them.

It releases the file

Other programs can reach it again, and your program is not holding a handle it no longer needs.

The handle survives

f still exists and f.closed is True. Reading or writing through it raises ValueError.

The last line is the wrong place

An exception above it means close() never runs. finally fixes that — and with does it for you.

Closing twice is harmless

A second close() on a closed file does nothing.

✍️ Now write these yourself
  1. 1

    Write a line into a file, and before closing it, open the same file again and print what is inside.

    Hint · Two handles at once. The second one reads the disk.

  2. 2

    Close a file and then call f.read() on it.

    Hint · ValueError: I/O operation on closed file.

  3. 3

    Print f.closed before and after f.close(), then call close() a second time.

    Hint · False, True — and the second close() is quietly ignored.

  4. 4

    Rewrite one of your file programs so the close() sits in a finally block.

    Hint · open() goes above the try; only the work goes inside it.

Quick Check

A program writes to a file and is stopped before close() runs. What is usually in the file?

Quick Check

What does f.close() give back?

Quick Check

What is the error when a program reads a file it has already closed?

Quick Check

Where should close() go so that it runs even when the program crashes?