Java ImageIO:异常奇怪现象

5
在我的应用程序中,我试图使用ImageIO将一个BufferedImage保存为PNG文件。由于文件是由用户选择的,所以我需要对可能发生的错误做出反应(例如,用户试图保存到没有写入权限的位置)。但是,我无法捕获发生的IOException。
以下代码显示了问题。在*nix系统上,尝试保存到“/foo”应该会对大多数用户抛出异常,因为他们在根目录下没有写入权限。
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!");
        }
    }
}

然而,异常未被捕获。输出:
    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)

请注意,FileNotFoundExceptionIOException 的子类,因此应该捕获它。第二个 catch 块也没有起到帮助作用。
catch (FileNotFoundException e) {
    System.out.println("Caught FileNotFoundException!");
} catch (IOException e) {
    System.out.println("Caught IOException!");
}

我做错了什么?

4个回答

6
这是一个与ImageIO实现细节相关的问题。如果您不将File实例传递给ImageIO.write,而是首先尝试自己打开一个FileOutputStream并将其传递给write,则可以避免该问题。
以下是ImageIO.write中发生的更精确的分析。在第1530行
stream = createImageOutputStream(output);

第1538行:

stream.close();

如果您查看createImageOutputStream的实现,您会发现几个返回null的代码路径。


4
看起来ImageIO.write方法会打印IOException,但实际上并不处理它,并以NullPointerException结束。在这种有缺陷的库的特定情况下,也许应该捕获任何RuntimeException...
当然,在进行操作前最好测试目录是否存在且可写

0

看起来 ImageIO.write()FileNotFoundException 包装成了 NullPointerException

你应该捕获 NullPointerException,或者更好的方法是在调用 ImageIO.write() 之前检查文件是否存在。


3
无法找到任何“由于”的因果关系来支持您的结论。 - Marko Topolnik

0
看起来FileNotFoundException在javax.imageio.ImageIO.write中被处理,而这个失败导致了空指针异常。在尝试保存之前,请检查文件权限!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接