GDAL处理文件后无法用os.remove删除:文件被占用问题求助
GDAL文件占用导致无法删除的解决方法
在处理遥感影像时,解压tar.gz中的TIFF文件后用GDAL读取波段数据,后续执行os.remove删除这些文件时,报错:
The process cannot access the file because it is being used by another process
尝试将波段数组变量设为None无效,推测是GDAL未释放文件句柄。
问题根源
你只释放了存储波段数据的数组(如Band1),但GDAL的Dataset对象(如Band1_ds)才是持有文件句柄的核心对象,这些对象没有被正确释放,导致文件被进程锁定,无法删除。
解决方案
- 用上下文管理器自动关闭GDAL数据集:GDAL 2.0及以上版本支持
with语句,会在代码块结束后自动释放数据集和文件句柄,这是最可靠的方式。 - 手动释放数据集对象:如果GDAL版本较低,在读取完数据和所需元数据后,立即将数据集变量设为
None。 - 关闭tar文件:原代码中打开tar文件后未关闭,也可能导致资源泄漏,建议用
with语句打开tar。
修改后的完整代码
import tarfile import os import xarray import tifffile import gdal import numpy as np def OC3(Band1, Band2, Band3): ratio = np.maximum(Band1, Band2) / Band3 ChloA = 10**(0.12825 - 2.04833 * ratio - 0.00187 * ratio**2 + 1.28644 * ratio**3 + 0.07052 * ratio**4) return ChloA def NDTI(Band3, Band4): NDTI = (Band4 - Band3) / (Band4 + Band3) return NDTI path = r"\\geo12\students\alengrand\test" extract_path = r"C:\Users\Alengrand\Desktop\Test" os.chdir(path) fname = os.listdir(".") print(fname) for i in range(len(fname)) : if fname[i].endswith("tar.gz") : # 用with语句打开tar,自动关闭避免资源泄漏 with tarfile.open(fname[i], "r:gz") as tar: files = tar.getnames() names = [] for file in files : if file.endswith(("AR_BAND1.tif", "AR_BAND2.tif", "AR_BAND3.tif", "AR_BAND4.tif")): names.append(file) for name in names : tar.extract(name, path=extract_path) extract_name = os.listdir(extract_path) Band1, Band2, Band3, Band4 = None, None, None, None geotransform = None projection = None for name in extract_name: if name.endswith("AR_BAND1.tif"): # 用with语句自动关闭GDAL数据集 with gdal.Open(f'{extract_path}/{name}') as ds: Band1 = ds.ReadAsArray().astype(float) Band1[Band1 < 0] = np.nan # 提前保存地理变换和投影信息 geotransform = ds.GetGeoTransform() projection = ds.GetProjection() elif name.endswith("AR_BAND2.tif"): with gdal.Open(f'{extract_path}/{name}') as ds: Band2 = ds.ReadAsArray().astype(float) Band2[Band2 < 0] = np.nan elif name.endswith("AR_BAND3.tif"): with gdal.Open(f'{extract_path}/{name}') as ds: Band3 = ds.ReadAsArray().astype(float) Band3[Band3 < 0] = np.nan elif name.endswith("AR_BAND4.tif"): with gdal.Open(f'{extract_path}/{name}') as ds: Band4 = ds.ReadAsArray().astype(float) Band4[Band4 < 0] = np.nan ChloA = OC3(Band1, Band2, Band3) Turb = NDTI(Band3, Band4) # 创建输出文件时也用with语句自动关闭 driver = gdal.GetDriverByName('GTiff') with driver.Create(r"C:\Users\alengrand\Desktop\ChloA.tif", ChloA.shape[1], ChloA.shape[0], 1, gdal.GDT_Float32) as ChloA_dataset: ChloA_dataset.SetGeoTransform(geotransform) ChloA_dataset.SetProjection(projection) ChloA_dataset.GetRasterBand(1).WriteArray(ChloA) with driver.Create(r"C:\Users\alengrand\Desktop\Turb.tif", Turb.shape[1], Turb.shape[0], 1, gdal.GDT_Float32) as Turb_dataset: Turb_dataset.SetGeoTransform(geotransform) Turb_dataset.SetProjection(projection) Turb_dataset.GetRasterBand(1).WriteArray(Turb) print("ChloA and Turb GeoTIFF files saved successfully.") # 删除文件 for filename in os.listdir(extract_path): file_path = os.path.join(extract_path, filename) if os.path.isfile(file_path): os.remove(file_path)
内容的提问来源于stack exchange,提问作者Aurélien Lengrand
相关产品推荐
相关产品推荐

