在java中打开具有相对路径的资源

时间:2009-02-21 20:26:29

标签: java resources loading

在我的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类。

关于文件,我试过

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

为了获得真正的路径,但这种方式不起作用。

我不知道怎么做目录。

12 个答案:

答案 0 :(得分:138)

我在使用getClass().getResource("filename.txt")方法时遇到了问题。 在阅读Java文档说明时,如果您的资源与您尝试访问资源的类不在同一个包中,则必须为其提供以'/'开头的相对路径。建议的策略是将资源文件放在根目录下的“resources”文件夹下。例如,如果你有结构:

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"文件夹

答案 1 :(得分:40)

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

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

答案 2 :(得分:30)

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

Project/
  src/                // application source code
    org/
      myproject/
        MyClass.java
  test/               // unit tests
  res/                // resources
    images/           // PNG images for icons
      my-image.png
    xml/              // XSD files for validating XML files with JAXB
      my-schema.xsd
    conf/             // default .conf file for Log4j
      log4j.conf
  lib/                // libraries added to build-path via project settings

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

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)

答案 3 :(得分:8)

@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);

答案 4 :(得分:7)

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

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

答案 5 :(得分:4)

对于那些使用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构建路径>源>删除/添加文件夹),我能够解决此问题。

答案 6 :(得分:2)

resourcesloader.class.getClass()

可以细分为:

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

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

相反,你可能想要这样的东西:

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

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

答案 7 :(得分:1)

从事以下工作?

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

是否有理由不能指定包含包的完整路径?

答案 8 :(得分:1)

按照上面提到的两个答案。第一个

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

应该是同一件事吗?

答案 9 :(得分: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();

答案 10 :(得分:0)

使用此:

resourcesloader.class.getClassLoader().getResource("/path/to/file").**getPath();**

答案 11 :(得分:0)

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

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

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

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

BufferedReader bufferedReader = new BufferedReader(
                        new InputStreamReader(fileUrl.openStream()));