So, you have encountered the exception/error, i.e., ValueError: I/O operation on closed file. In the following article, we will discuss value errors, how they occur and how to resolve them. You can also check out our other articles on ValueError here.
What is a ValueError & why it occurs?
The ValueError occurs when an argument is passed to the function that is of the correct type; however, an incorrect argument for the function. This may sound a little confusing. Let’s try to understand it using some examples.
Example 1:
print(int(22/7))
print(int("let's convert it to an integer"))
In the above example, converting a floating-point value returns an integer. However, trying the same thing on a string returns a ValueError.
Example 2:
import math
number = int(input("Enter number:"))
print(f"The square root of {number} is {math.sqrt(number)}.")
In the above example, getting a square root of a negative number returns a value error. This is because the sqrt function expects an integer value, not a negative(or a floating-point value).
The examples above must have cleared the concept of ValueError.
ValueError: I/O operation on closed file
ValueError: I/O operation on closed file can occur in the following two cases. Let’s look at them one by one.
Case 1:
When you try to read or write a file when it has been closed. To elaborate, when you open a file through context manager, perform read or write operations, and close it. However, if you try reading or writing on that file, it will throw a value error.
For instance, let’s look at an example.
with open('test.txt','w') as file:
file.write("This is the first line.\n")
file.write("This is second one.\n")
file.close()
file.write("This is the last line.")
In the code above, we try to open a file named test.txt, then perform some write operations on it and close the file. However, when we try to write another statement into it, ValueError gets thrown. This is a case of accessing a closed file.
Case 2:
with open('test.txt','w') as file:
file.write("This is the first line.\n")
file.write("This is second one.\n")
file.write("This is the last line.")
file.close()
In the code above, we try to open a file named test.txt then perform some write operations on it. However, the write function is used outside the with block. This is a case of incorrect indentation, and hence the ValueError is thrown.
Solution
For the first case, close the opened file only when you have finished all the operations. This will prevent the error raised.
with open('test.txt','w') as file:
file.write("This is the first line.\n")
file.write("This is second one.\n")
file.write("This is the last line.")
file.close()
While for the second case, you will need to indent your code under the with block to resolve the ValueError.
with open('test.txt','w') as file:
file.write("This is the first line.\n")
file.write("This is second one.\n")
file.write("This is the last line.")
file.close()
ValueError I/O operation on closed file CSV
For this example, we have taken grades.csv separated by ‘, ‘. Let’s print the names and grades of students. We have removed some lines for ease of understanding.
import csv
with open('grades.csv','r') as file:
csv_reader = csv.reader(file,delimiter=',')
next(csv_reader,None)
for row in csv_reader:
name = row[1].strip().strip('"') + ' ' + row[0]
grade = row[-1].strip().strip('"')
print(f'Name: {name}, Grade: {grade}')
- In the above code, we have opened the file and saved the reader object returned by csv.reader to csv_reader and also skipped the header of the csv using next function.
- Now if we try to iterate over the reader object an error gets thrown as the file has been closed by python automatically(on using with statement).
- To avoid this, the for loop is needed to be within with statement scope. This is to ensure that for loop has executed before the file being closed.
with open('grades.csv','r') as file:
csv_reader = csv.reader(file,delimiter=',')
print(type(csv_reader))
next(csv_reader,None)
for row in csv_reader:
name = row[1].strip().strip('"') + ' ' + row[0]
grade = row[-1].strip().strip('"')
print(f'Name: {name}, Grade: {grade}')
Django gives an “I/O operation on closed file” error when reading from a saved ImageField
If you have a simple model with an ImageField, the following code will return an error “I/O operation on closed file”.
instance = MyClass.objects.get(...)
w = instance.image.width
h = instance.image.height original = Image.open(instance.image)
Try reopening the file to avoid this error. For instance:
instance = MyClass.objects.get(...) w = instance.image.width h = instance.image.height instance.image.open() original = Image.open(instance.image)
ValueError i/o operation on closed file, BytesIO
BytesIO is used for manipulating bytes data in memory and is part of the io module. ValueError might creep in if the indentation is wrong or operations are being performed on a closed file.
import io
with io.BytesIO() as f:
f.write(b"This is the first line")
f.write(b"This is the second line")
# operation outside the with statement
f.write(b"This is the third line")
To resolve the error, indent the code or open the file again.
FAQs on ValueError: I/O operation on closed file
No, you can’t read and write on a closed file. If you try to do so, it will raise a ValueError. You can only perform read and write operations when the file is opened.
A quick fix is to downgrade to a version openpyxl==2.5.11
where this issue isn’t present.
This error occurs only when you try to do some operations on a closed file. Try checking for indentation of your code or whether the file is opened or not.
Conclusion
In this article, we tried to shed some light on the standard value error for beginners, i.e., ‘I/O operation on closed files’. We also understood why it happens, when it can occur, and its solutions.