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

Gia*_*rlo 76 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
Run Code Online (Sandbox Code Playgroud)

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

至于文件,我试过了

resourcesloader.class.getClass().getResource("repository/SSL-Key/cert.jks").toString()
Run Code Online (Sandbox Code Playgroud)

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

我不知道如何做目录.

Joh*_*nny 146

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

src/main/com/mycompany/myapp
Run Code Online (Sandbox Code Playgroud)

然后你可以按照maven的推荐添加资源文件夹:

src/main/resources
Run Code Online (Sandbox Code Playgroud)

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

src/main/resources/textfiles
Run Code Online (Sandbox Code Playgroud)

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

src/main/resources/textfiles/myfile.txt
Run Code Online (Sandbox Code Playgroud)

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

"/main/resources/textfiles/myfile.txt" path
Run Code Online (Sandbox Code Playgroud)

要么

"/resources/textfiles/myfile.txt"
Run Code Online (Sandbox Code Playgroud)

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

myapp/target/classes 
Run Code Online (Sandbox Code Playgroud)

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

myapp/target/classes/textfiles/myfile.txt

myapp/target/classes/com/mycompany/myapp/*
Run Code Online (Sandbox Code Playgroud)

所以给这个getClass().getResource("")方法的正确途径是:

"/textfiles/myfile.txt"
Run Code Online (Sandbox Code Playgroud)

这里是:

getClass().getResource("/textfiles/myfile.txt")
Run Code Online (Sandbox Code Playgroud)

这将不再返回null,但会返回您的类.我希望这有助于某人.我很奇怪,"resources"文件夹也没有被复制,只有子文件夹和文件直接在"resources"文件夹中.对我来说,这个"resources"文件夹也可以找到"myapp/target/classes"


jon*_*one 43

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

resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();
Run Code Online (Sandbox Code Playgroud)


E-r*_*ich 32

希望为那些不像其他人那样快速提取信息的人提供额外的信息,我想提供我的场景,因为它的设置略有不同.我的项目使用以下目录结构进行设置(使用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目录添加到构建路径,然后通过以下方式访问资源:

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

注:/,因为我用的是从资源字符串的开头省略 ClassLoader.getResource方法,(串),而不是Class.getResource(字符串).


Vik*_*ram 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);
Run Code Online (Sandbox Code Playgroud)


nbe*_*yer 8

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

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


小智 5

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

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

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