The i/o operations in Python are performed when the file is in an open state. So if we are trying to read or write into a file that is already closed state Python interpreter will raise the ValueError: I/O operation on closed file.
In this article, we will look at what is ValueError: I/O operation on closed file and how to resolve this error with examples.
ValueError: I/O operation on closed file
The best practice during file operations is to close the file as soon as we perform the operations with the file. It helps to free the resources such as memory and computing and also helps improve the overall performance. Once the file is closed, you can no longer access the file and perform read/write operations on that file.
There are three main common reasons why we face the ValueError: I/O operation on closed file.
- First, when you try, forget to indent the code in the
with
statement. - Second, when you try to read/write to a file in a closed state.
- Third, when you close the file inside a for loop, accidentally
Let us look at an example where we can reproduce the issue.
Scenario 1 – Improper Indentation
We have a simple code to read the CSV file, which consists of employee data. First, we have imported the CSV library, and then we used a with
statement to open the CSV file in a read mode,
Once the file is opened, we call the method csv.reader()
to read the file contents and assign the contents into the read_csv variable.
Later, using the for loop, we iterated the file contents and printed each file row.
Let us run this code and see what happens.
import csv
# Open the file in read mode
with open("employee.csv", "r") as employees:
read_csv = csv.reader(employees)
# iterate and print the rows of csv
for row in read_csv:
print("Rows: ", row)
Traceback (most recent call last):
File "c:\Personal\IJS\Code\prgm.py", line 8, in <module>
for row in read_csv:
ValueError: I/O operation on closed file.
Solution
The above code has returned ValueError because we tried to iterate the read_csv
outside the with
statement. The with
statement acts as a file context, and once it’s executed, it will automatically close the file. Hence any file operation outside the with
statement will lead to this error.
We can resolve the code by properly indenting our code and placing it inside the with
statement context. But, first, let us look at the revised code.
import csv
# Open the file in read mode
with open("employee.csv", "r") as employees:
read_csv = csv.reader(employees)
# iterate and print the rows of csv
for row in read_csv:
print("Rows: ", row)
Output
Rows: ['EmpID', 'Name', 'Age']
Rows: ['1', 'Chandler Bing', ' 22']
Rows: ['2', 'Jack', '21']
Rows: ['3', 'Monica', '33']
Scenario 2 – Accessing the closed file
It is the most common and best practice to use with
statements for accessing the files. We can also access the file without using the with
statement by just using the open()
method as shown below.
Once the file is open, using the csv.reader()
method we have read the contents of the file and assigned it to a variable read_csv
.
Then, we closed the file as the contents are read and stored to a variable. Next, we iterate the read_csv
variable using a for
loop and print each row of the CSV file.
Let us execute the code and see what happens.
import csv
# open file in read mode
employees = open("employee.csv", "r")
read_csv = csv.reader(employees)
employees.close()
# iterate and print the eac row
for row in read_csv:
print("Rows: ", row)
Output
Traceback (most recent call last):
File "c:\Personal\IJS\Code\prgm.py", line 9, in <module>
for row in read_csv:
ValueError: I/O operation
Solution
The fix here is straightforward; we need to ensure that the file is closed after the for
loop. The read_csv
file holds a reference of the file object, and if we close the file, it will not be able to access the file and perform any I/O operations.
Let us fix the issue and execute the code.
import csv
# open file in read mode
employees = open("employee.csv", "r")
read_csv = csv.reader(employees)
# iterate and print the eac row
for row in read_csv:
print("Rows: ", row)
# close the file after iteraating and printing
employees.close()
Output
Rows: ['EmpID', 'Name', 'Age']
Rows: ['1', 'Chandler Bing', ' 22']
Rows: ['2', 'Jack', '21']
Rows: ['3', 'Monica', '33']
Scenario 3 – Closing the file inside a for loop
There could be another scenario where we do not correctly indent the code, which can lead to this issue.
For example, in the below code, we are opening the file and reading the file contents using csv.reader()
method.
Next, using the for
loop, we are iterating the CSV rows and printing each row. We have placed the file close()
method inside the for
loop accidentally, which will lead to an issue.
The loop executes and prints the first record successfully, and after that, it will close the file, and it won’t be able to access any other rows in the CSV.
import csv
# open file in read mode
employees = open("employee.csv", "r")
read_csv = csv.reader(employees)
# iterate and print the eac row
for row in read_csv:
print("Rows: ", row)
employees.close()
Output
Rows: ['EmpID', 'Name', 'Age']
Traceback (most recent call last):
File "c:\Personal\IJS\Code\prgm.py", line 8, in <module>
for row in read_csv:
ValueError: I/O operation on closed file.
Solution
We can resolve the issue by placing the close()
statement outside the for
loop. This will ensure that file contents are iterated and printed correctly, and after that, the file is closed.
Let us revise our code and execute it.
import csv
# open file in read mode
employees = open("employee.csv", "r")
read_csv = csv.reader(employees)
# iterate and print the eac row
for row in read_csv:
print("Rows: ", row)
employees.close()
Output
Rows: ['EmpID', 'Name', 'Age']
Rows: ['1', 'Chandler Bing', ' 22']
Rows: ['2', 'Jack', '21']
Rows: ['3', 'Monica', '33']
Conclusion
The ValueError: I/O operation on closed file occurs if we are trying to perform the read or write operations on the file when it’s already in a closed state.
We can resolve the error by ensuring that read and write operations are performed when the file is open. If we use the with
statement to open the file, we must ensure the code is indented correctly. Once the with
statement is executed, the file is closed automatically. Hence any I/O operation performed outside the with
statement will lead to a ValueError.