Search code examples
javajavax.imageiopaint.net

Java ImageIO claims image


I'm working on an application which reloads an image every once in a while. I did that so I could make changes on the go externally. I'm using ImageIO.read(path) to read the image file.

Now when I want to change the image with my paint.NET and try to save(overwrite) the image, paint.NET throws an IOException. This is probably because ImageIO just claims the image to be his while the process is running. But that's what I think.

The Code is here:

public int width, height;
public int[] pixels;

public Sprite(String ref) {
    try {
        BufferedImage image = ImageIO.read(new FileInputStream(ref));
        width = image.getWidth();
        height = image.getHeight();
        pixels = new int[width * height];
        pixels = image.getRGB(0, 0, width, height, pixels, 0, width);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Anyone knows how to fix this?

Thanks!


Solution

  • On Windows (I assume you're on Windows, as you mention you use Paint.NET), holding onto a file is particularly problematic, as it will prevent other applications from writing to that same file. Most likely, this is the problem you encounter.

    When you open a stream, like you do here:

    new FileInputStream(ref);
    

    You acquire a native file pointer. It is your responsibility to close it again after use, to release the file pointer. Now, ImageIO.read(InputStream) should close the stream for you, but in certain cases and certain versions of Java, there has been bugs related to this. If the stream is not properly closed, the Java process will hold onto this file pointer as a worst case until the Java process terminates.

    The good news, is that if you simply change your code to:

    BufferedImage image = ImageIO.read(new File(ref));
    

    Then ImageIO will always take care of the opening and closing of the stream.