Reputation: 707
In my application I was trying to save a BufferedImage
to a PNG file using ImageIO
. The file is chosen by the user so I need to react to errors that might happend (e.g. user tries to save in a location he has no write permission for). However I am unable to catch the IOException
that occurs.
The following code shows the problem. Trying to save to "/foo" should throw an exception for most users on *nix systems, since they do not have write permission in the root directory.
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class IOTest {
public static void main(String[] args) {
BufferedImage img = new BufferedImage(640, 480,
BufferedImage.TYPE_INT_RGB);
try {
File f = new File("/foo");
ImageIO.write(img, "png", f);
} catch (IOException e) {
System.out.println("Caught IOException!");
}
}
}
However, the exception is not caught. Output:
java.io.FileNotFoundException: /foo (Permission denied)
at java.io.RandomAccessFile.open(Native Method)
at java.io.RandomAccessFile.<init>(RandomAccessFile.java:233)
at javax.imageio.stream.FileImageOutputStream.<init>(FileImageOutputStream.java:69)
at com.sun.imageio.spi.FileImageOutputStreamSpi.createOutputStreamInstance(FileImageOutputStreamSpi.java:55)
at javax.imageio.ImageIO.createImageOutputStream(ImageIO.java:419)
at javax.imageio.ImageIO.write(ImageIO.java:1530)
at IOTest.main(IOTest.java:16)
Exception in thread "main" java.lang.NullPointerException
at javax.imageio.ImageIO.write(ImageIO.java:1538)
at IOTest.main(IOTest.java:16)
Note that FileNotFoundException
is a subclass of IOException
so it should get caught. A second catch block did not help either:
catch (FileNotFoundException e) {
System.out.println("Caught FileNotFoundException!");
} catch (IOException e) {
System.out.println("Caught IOException!");
}
What am I doing wrong?
Upvotes: 5
Views: 5067
Reputation: 200296
It stems from the details of ImageIO
implementation. You will circumvent the problem if you don't pass the File
instance to ImageIO.write
, but first try to open a FileOutputStream
yourself and pass that to write
.
This is a more precise analysis of what happens in ImageIO.write
. Line 1530:
stream = createImageOutputStream(output);
stream.close();
And if you take a look at the implementation of createImageOutputStream
, you'll see several code paths that return null
.
Upvotes: 6
Reputation: 4067
By the looks of it the FileNotFoundException is being handled within javax.imageio.ImageIO.write and that failure is causing a null pointer exception. Try to check the file permissions before you try saving it!
Upvotes: 0
Reputation: 3409
It seems that ImageIO.write()
wraps the FileNotFoundException
into a NullPointerException
.
You should catch NullPointerException
, or better check file existence before invoking ImageIO.write()
.
Upvotes: 0
Reputation: 382464
It looks like the ImageIO.write
method prints the IOException
but really doesn't handle it and ends with a NullPointerException
. In this specific case of a buggy library, maybe you should catch any RuntimeException
...
Of course it will be better to test before if the directory exists and is writable.
Upvotes: 4