89

在我的 Java 应用程序中,我需要获取一些文件和目录。

这是程序结构:

./main.java
./package1/guiclass.java
./package1/resources/resourcesloader.java
./package1/resources/repository/modules/   -> this is the dir I need to get
./package1/resources/repository/SSL-Key/cert.jks    -> this is the file I need to get

guiclass加载将加载我的资源(目录和文件)的资源加载器类。

至于文件,我试过

resourcesloader.class.getClass().getResource("repository/SSL-Key/cert.jks").toString()

为了得到真正的路径,但这种方式行不通。

我不知道该目录使用哪个路径。

4

13 回答 13

175

我在使用该getClass().getResource("filename.txt")方法时遇到了问题。在阅读 Java 文档说明后,如果您的资源与您尝试从中访问资源的类不在同一个包中,那么您必须为其提供以'/'. 推荐的策略是将您的资源文件放在根目录中的“资源”文件夹下。因此,例如,如果您具有以下结构:

src/main/com/mycompany/myapp

然后您可以按照 maven 的建议添加资源文件夹:

src/main/resources

此外,您可以在资源文件夹中添加子文件夹

src/main/resources/textfiles

并说你的文件被调用myfile.txt所以你有

src/main/resources/textfiles/myfile.txt

现在这是愚蠢的路径问题出现的地方。假设您的 中有一个类com.mycompany.myapp package,并且您想myfile.txt从资源文件夹中访问该文件。有人说你需要提供:

"/main/resources/textfiles/myfile.txt" path

或者

"/resources/textfiles/myfile.txt"

这两个都是错误的。运行后mvn clean compile,文件和文件夹被复制到:

myapp/target/classes 

文件夹。但是资源文件夹不存在,只有资源文件夹中的文件夹。所以你有了:

myapp/target/classes/textfiles/myfile.txt

myapp/target/classes/com/mycompany/myapp/*

所以给予该getClass().getResource("")方法的正确路径是:

"/textfiles/myfile.txt"

这里是:

getClass().getResource("/textfiles/myfile.txt")

这将不再返回 null,而是返回您的类。我希望这对某人有所帮助。我很奇怪,该"resources"文件夹也没有被复制,而只是文件夹中的子文件夹和文件"resources"。在我看来,该"resources"文件夹也可以在下面找到"myapp/target/classes"

于 2010-01-20T17:50:45.087 回答
50

提供相对于类加载器的路径,而不是您从中获取加载器的类。例如:

resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();
于 2009-02-21T20:46:13.220 回答
36

希望为那些没有像其他人那样快速掌握它的人提供更多信息,我想提供我的场景,因为它的设置略有不同。我的项目使用以下目录结构设置(使用 Eclipse):

项目/
  src/ // 应用程序源代码
    组织/
      我的项目/
        MyClass.java
  test/ // 单元测试
  res/ // 资源
    images/ // 图标的 PNG 图像
      我的图像.png
    xml/ // XSD 文件,用于使用 JAXB 验证 XML 文件
      我的架构.xsd
    conf/ // Log4j 的默认 .conf 文件
      log4j.conf
  lib/ // 通过项目设置添加到构建路径的库

我在从res目录加载资源时遇到问题。我希望我的所有资源都与我的源代码分开(仅出于管理/组织目的)。所以,我要做的就是将res目录添加到构建路径,然后通过以下方式访问资源:

static final ClassLoader loader = MyClass.class.getClassLoader();

// in some function
loader.getResource("images/my-image.png");
loader.getResource("xml/my-schema.xsd");
loader.getResource("conf/log4j.conf");

注意:资源字符串的/开头省略了 ,因为我使用的是 ClassLoader.getResource(String)而不是Class.getResource(String)

于 2011-06-20T19:08:49.483 回答
10

在 Class 上使用“getResource”时,将根据 Class 所在的包解析相对路径。在 ClassLoader 上使用“getResource”时,将根据根文件夹解析相对路径。

如果您使用绝对路径,则两个“getResource”方法都将从根文件夹开始。

于 2009-02-22T00:10:36.067 回答
10

@GianCarlo:您可以尝试调用系统属性 user.dir ,它将为您提供 java 项目的根目录,然后将此路径附加到您的相对路径,例如:

String root = System.getProperty("user.dir");
String filepath = "/path/to/yourfile.txt"; // in case of Windows: "\\path \\to\\yourfile.txt
String abspath = root+filepath;



// using above path read your file into byte []
File file = new File(abspath);
FileInputStream fis = new FileInputStream(file);
byte []filebytes = new byte[(int)file.length()];
fis.read(filebytes);
于 2010-10-21T00:27:34.897 回答
6

对于那些使用 eclipse + maven 的人。假设您尝试访问images/pic.jpg. src/main/resources这样做:

ClassLoader loader = MyClass.class.getClassLoader();
File file = new File(loader.getResource("images/pic.jpg").getFile());

完全正确,但可能导致空指针异常。似乎 eclipse 无法立即将 maven 目录结构中的文件夹识别为源文件夹。通过src/main/resources从项目的源文件夹列表中删除文件夹并将其放回(项目>属性>java构建路径>源>删除/添加文件夹),我能够解决这个问题。

于 2015-10-27T12:55:05.653 回答
2
resourcesloader.class.getClass()

可以分解为:

Class<resourcesloader> clazz = resourceloader.class;
Class<Class> classClass = clazz.getClass();

这意味着您正在尝试使用引导类加载资源。

相反,您可能想要类似的东西:

resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString()

如果只有 javac 警告在非静态上下文中调用静态方法...

于 2009-02-21T20:52:43.250 回答
1

以下工作吗?

resourcesloader.class.getClass().getResource("/package1/resources/repository/SSL-Key/cert.jks")

您是否有理由不能指定包括包在内的完整路径?

于 2009-02-21T20:45:44.873 回答
1

与上面提到的两个答案一起去。第一个

resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();
resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString()

应该是一回事吗?

于 2011-12-11T08:51:19.557 回答
1

为了获得文件的真实路径,您可以尝试以下操作:

URL fileUrl = Resourceloader.class.getResource("resources/repository/SSL-Key/cert.jks");
String pathToClass = fileUrl.getPath;    

Resourceloader 在这里是类名。“resources/repository/SSL-Key/cert.jks”是文件的相对路径。如果您的 ./package1/java 中的 guiclass 保留了其余的文件夹结构,则由于定义了相对路径的规则,您会将“../resources/repository/SSL-Key/cert.jks”作为相对路径。

这样您就可以使用 BufferedReader 读取文件。不要使用字符串来标识文件的路径,因为如果路径中有空格或某些非英文字母的字符,则会出现问题并且找不到文件。

BufferedReader bufferedReader = new BufferedReader(
                        new InputStreamReader(fileUrl.openStream()));
于 2019-08-13T17:36:52.503 回答
0

我对@jonathan.cone 的一个衬里进行了小修改(通过添加.getFile())以避免空指针异常,并设置数据目录的路径。这对我有用:

String realmID = new java.util.Scanner(new java.io.File(RandomDataGenerator.class.getClassLoader().getResource("data/aa-qa-id.csv").getFile().toString())).next();
于 2016-04-27T17:42:32.270 回答
0

用这个:

resourcesloader.class.getClassLoader().getResource("/path/to/file").**getPath();**
于 2017-02-28T16:00:10.527 回答
0

在所有操作系统上工作的稳定方法之一是System.getProperty("user.dir")

String filePath = System.getProperty("user.dir") + "/path/to/file.extension";

Path path = Paths.get(filePath);
if (Files.exists(path)) {
    return true;
}
于 2021-09-19T14:41:32.587 回答