You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)才是持有文件句柄的核心对象,这些对象没有被正确释放,导致文件被进程锁定,无法删除。

解决方案

  1. 用上下文管理器自动关闭GDAL数据集:GDAL 2.0及以上版本支持with语句,会在代码块结束后自动释放数据集和文件句柄,这是最可靠的方式。
  2. 手动释放数据集对象:如果GDAL版本较低,在读取完数据和所需元数据后,立即将数据集变量设为None。
  3. 关闭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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 19:34:53