getClassLoader()。getResource()抛出NullPointerException?为什么不FileNotFoundException?

时间:2015-03-10 22:34:19

标签: java file io nullpointerexception

我正在尝试在我正在处理的程序中加载文件。我是通过使用getClassLoader()。getResource()来做到这一点的。当文件能够找到时,这非常有效。但是,当找不到该文件时,它会抛出NullPointerException。不应该抛出FileNotFoundException,或者getResource()只是不抛出这样的异常?

这是代码(非常标准的文件加载):

public static File loadFile(String path) throws FileNotFoundException
{
    return new File(FileHandler.class.getClassLoader().getResource(path).getFile());
}

//somewhere else
loadFile("data/xt.txt");

如果存在xt.txt,代码工作正常。如果没有,它会抛出NullPointerException。我可以轻松地修改我的代码来处理NullPointerException,但我想不出为什么它首先返回null而不是FileNotFound。

3 个答案:

答案 0 :(得分:4)

getResource 不会抛出异常。如果找不到资源,则返回null

您的代码在尝试对getFile返回的空引用上调用getResource时抛出异常。

你可以这样做:

URL resourceURL = FileHandler.class.getClassLoader().getResource(path);
if(resourceURL == null)
    throw new FileNotFoundException(path+" not found");
return new File(resourceURL.getFile());

答案 1 :(得分:2)

此代码抛出NullPointerException,因为:

    如果找不到资源,
  1. FileHandler.class.getClassLoader().getResource(path)会返回null - 它在Java规范中以这种方式定义。

  2. .getFile()上调用null是一个NullPointerException。

  3. 那就是说,请注意:

    • 资源不一定是文件,因此FileNotFoundException通常不适合资源。

    • 如果文件不存在,File类的构造函数会抛出异常。您可以使用File.exists()来检查文件是否确实存在。

答案 2 :(得分:0)

好的,所以我遇到了这个问题。这是我的解决方法,但我讨厌必须这样做。

这里是情况和解决方法: 我在Mac上运行代码。我有一个res文件夹,里面有我的数据库结构。 getResource命令如下所示:

ArchiverSQL a = new ArchiverSQL();
File file = new File(a.getClass().getResource("/database/structure/settings.sql").getFile()); 
   try (FileReader reader = new FileReader(file);
       BufferedReader br = new BufferedReader(reader)) {

       String line;
       while ((line = br.readLine()) != null) {
           System.out.println(line);
       }
   }

然后,当运行此代码时,我收到FileNotFound错误。 /Volumes/MainFiles%201/Code/IdeaProjects/theProgram/target/classes/database/structure/settings.sql MainFiles%201应该读为“ MainFiles 1”,由于某种原因,如果我使用由getResource()函数生成的%201,它将找不到该文件。

这就是我要做的,这使我很生气。

File file = new File(a.getClass().getResource("/database/structure/settings.sql")
.getFile().replaceAll("%20","\\ "));

我必须调整以“ \”返回的字符串,该字符串将变为“ \”,然后所有这些魔术再次起作用。我有一种感觉,因为我的软件在两个平台上都可以使用,所以现在我必须为Windows编写它的另一面。

希望这对其他遇到此问题的人有所帮助,如果您有更好的解决方案,请告诉我。