gisgeotools

Why can't I delete the tif file after releasing the resources?


I want to read bbox of this tiff, after completion I want to delete this tiff, There seems to be an unclosed stream causing the tiff to not be deleted.

public static void main(String[] args) throws Exception {
        File file = new File("E:\\test\\1\\昂多.tif");
        GeoTiffReader reader = new GeoTiffReader(file);
        GridCoverage2D read = reader.read(null);
        Envelope2D coverageEnvelope = read.getEnvelope2D();
        Rectangle2D bounds2D = coverageEnvelope.getBounds2D();
        double[] bbox = {
                bounds2D.getMinX(), bounds2D.getMinY(),
                bounds2D.getMaxX(), bounds2D.getMaxY()
        };
        for (double v : bbox) {
            System.out.println(v);
        }
        read.dispose(true);
        reader.dispose();
        FileUtils.forceDelete(file);
    }

code running result


98.408460773
30.078745248
98.460743439
30.115231446
Exception in thread "main" java.io.IOException: Unable to delete file: E:\test\1\昂多.tif
    at org.apache.commons.io.FileUtils.forceDelete(FileUtils.java:2400)
    at cn.gisdata.core.publish.strategyImpl.Test.main(Test.java:37)

Process finished with exit code 1

GeoTools GridCoverage2D dispose(boolean force) api doc

public boolean dispose(boolean force)
Provides a hint that a coverage will no longer be accessed from a reference in user space. This method disposes the image only if at least one of the following conditions is true (otherwise this method do nothing):
force is true, or
The underlying image has no sinks.
This safety check helps to prevent the disposal of an image that still used in a JAI operation chain. It doesn't prevent the disposal in every cases however. When unsure about whatever a coverage is still in use or not, it is safer to not invoke this method and rely on the garbage collector instead.

Overrides:
dispose in class AbstractCoverage
Parameters:
force - true for forcing an inconditionnal disposal, or false for performing a conservative disposal. The recommanded value is false.
Returns:
true if this method disposed at least some resources, or false if this method vetoed against the disposal.
Since:
2.4
See Also:
PlanarImage.dispose()

Solution

  • modify the code

    public static void main(String[] args) throws Exception {
            File file = new File("E:\\test\\1\\昂多.tif");
            GridCoverage2D read = null;
            GeoTiffReader reader = null;
            try (FileInputStream is = new FileInputStream(file)){
                reader = new GeoTiffReader(is);
                read = reader.read(null);
                Envelope2D coverageEnvelope = read.getEnvelope2D();
                Rectangle2D bounds2D = coverageEnvelope.getBounds2D();
                double[] bbox = {
                        bounds2D.getMinX(), bounds2D.getMinY(),
                        bounds2D.getMaxX(), bounds2D.getMaxY()
                };
                for (double v : bbox) {
                    System.out.println(v);
                }
            }finally {
                read.dispose(true);
                reader.dispose();
                FileUtils.forceDelete(file);
            }
    
        }
    

    code running result

    98.408460773
    30.078745248
    98.460743439
    30.115231446
    
    Process finished with exit code 0
    

    GeoTiffReader construction method accept inputStream, So this input stream is controlled by me to close

    if (this.source instanceof InputStream || this.source instanceof ImageInputStream) {
                    this.closeMe = false;
                }