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

getClassLoader().getResource() throwing NullPointerException? Why not FileNotFoundException?

我正在尝试在我正在处理的程序中加载文件。我是通过使用 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。

getResource 不会 抛出异常。 returns null 如果找不到资源。

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

你可以这样做:

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

此代码抛出 NullPointerException,因为:

  1. FileHandler.class.getClassLoader().getResource(path) returns null 如果没有找到资源——它在 Java 规范中是这样定义的。

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

也就是说,请注意:

  • 资源不一定是文件,所以FileNotFoundException一般不适合资源。

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

好的,我遇到了这个问题。这就是我修复它的方法,但我讨厌我必须这样做。

这是情况和修复: 我正在 运行ning 代码 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 写下它的另一面,因为我的软件可以在两个平台上运行。

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