Java ImageIO:异常怪异

Wak*_*iko 5 java io exception filenotfoundexception ioexception

在我的应用程序中,我试图使用保存BufferedImage到PNG文件ImageIO.该文件由用户选择,因此我需要对可能发生的错误做出反应(例如,用户试图保存在他没有写入权限的位置).但是我无法IOException理解这种情况.

以下代码显示了该问题.尝试保存到"/ foo"应该为*nix系统上的大多数用户抛出异常,因为它们在根目录中没有写入权限.

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!");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,没有捕获异常.输出:

    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)
Run Code Online (Sandbox Code Playgroud)

请注意,它FileNotFoundException是一个子类,IOException所以它应该被捕获.第二个捕获块也没有帮助:

catch (FileNotFoundException e) {
    System.out.println("Caught FileNotFoundException!");
} catch (IOException e) {
    System.out.println("Caught IOException!");
}
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

Mar*_*nik 6

它源于ImageIO实施细节.如果你没有传递File实例ImageIO.write,你将绕过问题,但首先尝试打开一个FileOutputStream自己并将其传递给write.

这是对发生的事情进行更精确的分析ImageIO.write.1530行:

stream = createImageOutputStream(output);
Run Code Online (Sandbox Code Playgroud)

1538行:

stream.close();
Run Code Online (Sandbox Code Playgroud)

如果你看看实现createImageOutputStream,你会看到几个返回的代码路径null.