geotools加载tif 无法关闭tif的流导致tif文件无法删除问题
问题
使用如下代码,虽然调用了 dispose 方法,但是却没有释放 tif 的 io 流,会导致文件删除失败
public static void main(String[] args) throws IOException {File file = new File("D:\\1.tif");//此处会加载一次tif,但加载完会直接closeGeoTiffReader reader = new GeoTiffReader(file);//此处也会加载一次tif,但却无法关闭,即使调用disposeGridCoverage2D read = reader.read(null);
// read.dispose(true);reader.dispose();if (!file.delete()) {System.out.println("删除失败");}
}
相关依赖
<dependency><groupId>org.geotools</groupId><artifactId>gt-geotiff</artifactId><version>21.1</version>
</dependency>
解决方案
如下所示,自己获取文件的 io 流关闭
public static void main(String[] args) throws IOException {File file = new File("D:\\Desktop\\taiwan\\L14/den.tif");//此处会加载一次tif,但加载完会直接closeGeoTiffReader reader = new GeoTiffReader(file);//此处也会加载一次tif,但却无法关闭,即使调用disposeGridCoverage2D read = reader.read(null);//使用如下代码关闭流RenderedOp renderedImage = (RenderedOp) read.getRenderedImage();for (Object parameter : renderedImage.getParameters()) {if (parameter instanceof ImageInputStream) {((ImageInputStream) parameter).close();}}read.dispose(true);reader.dispose();if (!file.delete()) {System.out.println("删除失败");}
}
原因分析
只会贴几个核心地方的代码,不会全贴
如下两张图所示GeoTiffReader.reader在411行会创建一个读取 tif的 ImageInputStream 添加到ParameterBlock里,然后创建组合ParameterBlock的RenderOp ,之后再创建组合RenderOp 的GridCoverage2D 返回。注意,此处的pbjRead.add 是添加ImageInputStream 到ParameterBlock 的parameters 中。


然后在GridCoverage2D 的dispose中用调用 image的 dispose,此处的image即上面的RenderOp,
可以自己去看 image的 dispose ,可以发现并没有循环ParameterBlock 的parameters 关闭 ImageInputStream

而 read.getRenderedImage() 可以拿到 RenderOp, 所以就可以自己循环ParameterBlock 的parameters 释放 ImageInputStream 从而解决问题
