I have a program where I need to keep some objects that open files on disk list and delete those files after the program is done. However Python seems to be keeping the file open even though there are no more references to an object that should have it open. I've been able to recreate the problem with pure file objects below:
import os
filenames = ['a.txt', 'b.txt']
files = [open(f,'w') for f in filenames]
for f_object in files:
f_object.write("test")
del files[:]
for name in filenames:
os.remove(name)
When I run this on Windows I get the error
Traceback (most recent call last):
File ".\file_del.py", line 11, in <module>
os.remove(name)
WindowsError: [Error 32] The process cannot access the file because it is being used by another process: 'b.txt'
Interesting that it is able to delete a.txt without a problem. What is causing b.txt file to be open even though the references to it are gone?
Update
In the original problem, I don't have access to the files to close them. Trust me, I would love to close those files. See the following:
base_uri = 'dem'
out_uri = 'foo.tif'
new_raster_from_base_uri(base_uri, out_uri, 'GTiff', -1, gdal.GDT_Float32)
ds = []
for filename in [out_uri]:
ds.append(gdal.Open(filename, gdal.GA_Update))
band_list = [dataset.GetRasterBand(1) for dataset in ds]
for band in band_list:
for row_index in xrange(band.YSize):
a = numpy.zeros((1, band.XSize))
band.WriteArray(a, 0, row_index)
for index in range(len(ds)):
band_list[index] = None
ds[index] = None
del ds[:]
os.remove(out_uri)
Update 2
I've marked millimoose's answer as the correct one below since it fixes the issue with the abstracted problem of files that I presented here. Unfortuantely it didn't work with the GDAL objects I was using. For future reference, I dug deep and found the undocumented gdal.Dataset.__destroy_swig__(ds) function which seems to at least close the file that the dataset is associated with. I call that first before deleting the file on disk associated with the datasets and that seems to work.
The scope of the loop variable f_object is actually the surrounding function / module. that means it retains a reference to the last file from the iteration even if you clear the list. The following works properly:
import os
filenames = ['a.txt', 'b.txt']
files = [open(f,'w') for f in filenames]
for f_object in files:
f_object.write("test")
del files[:]
# Nuke the last reference.
del f_object
for name in filenames:
os.remove(name)
I suppose in your original code it would be del band. Alternately, move the loop into a function to avoid the loop variable leaking:
import os
def write_to_files(files):
for f_object in files:
f_object.write("test")
filenames = ['a.txt', 'b.txt']
files = [open(f,'w') for f in filenames]
write_to_files(files)
del files[:]
for name in filenames:
os.remove(name)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With