Java中使用相对路径打开资源

发布于 2024-07-14 09:14:12 字数 571 浏览 6 评论 0原文

在我的 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()

获取真实路径,但这种方法行不通。

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

In my Java app I need to get some files and directories.

This is the program structure:

./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 loads the resourcesloader class which will load my resources (directory and file).

As to the file, I tried

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

in order to get the real path, but this way does not work.

I have no idea which path to use for the directory.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

月光色 2024-07-21 09:14:12

我在使用 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 包中有一个类,并且您想要访问 myfile.txt 文件从您的资源文件夹中。 有人说你需要给出:

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

或者

"/resources/textfiles/myfile.txt"

这两者都是错误的。 运行 mvn cleancompile 后,文件和文件夹将复制到:

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”下找到,这似乎是合乎逻辑的

I had problems with using the getClass().getResource("filename.txt") method.
Upon reading the Java docs instructions, if your resource is not in the same package as the class you are trying to access the resource from, then you have to give it relative path starting with '/'. The recommended strategy is to put your resource files under a "resources" folder in the root directory. So for example if you have the structure:

src/main/com/mycompany/myapp

then you can add a resources folder as recommended by maven in:

src/main/resources

furthermore you can add subfolders in the resources folder

src/main/resources/textfiles

and say that your file is called myfile.txt so you have

src/main/resources/textfiles/myfile.txt

Now here is where the stupid path problem comes in. Say you have a class in your com.mycompany.myapp package, and you want to access the myfile.txt file from your resource folder. Some say you need to give the:

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

or

"/resources/textfiles/myfile.txt"

both of these are wrong. After I ran mvn clean compile, the files and folders are copied in the:

myapp/target/classes 

folder. But the resources folder is not there, just the folders in the resources folder. So you have:

myapp/target/classes/textfiles/myfile.txt

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

so the correct path to give to the getClass().getResource("") method is:

"/textfiles/myfile.txt"

here it is:

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

This will no longer return null, but will return your class.
It is strange to me, that the "resources" folder is not copied as well, but only the subfolders and files directly in the "resources" folder. It would seem logical to me that the "resources" folder would also be found under `"myapp/target/classes"

-小熊_ 2024-07-21 09:14:12

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

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

Supply the path relative to the classloader, not the class you're getting the loader from. For instance:

resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();
长不大的小祸害 2024-07-21 09:14:12

为了给那些不像其他人那样快速掌握这一点的人提供更多信息,我想提供我的场景,因为它的设置略有不同。 我的项目使用以下目录结构进行设置(使用 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)

In the hopes of providing additional information for those who don't pick this up as quickly as others, I'd like to provide my scenario as it has a slightly different setup. My project was setup with the following directory structure (using 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

I was having issues loading my resources from the res directory. I wanted all my resources separate from my source code (simply for managment/organization purposes). So, what I had to do was add the res directory to the build-path and then access the resource via:

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

NOTE: The / is omitted from the beginning of the resource string because I am using ClassLoader.getResource(String) instead of Class.getResource(String).

野侃 2024-07-21 09:14:12

当您在类上使用“getResource”时,将根据类所在的包解析相对路径。在类加载器上使用“getResource”时,将根据根文件夹解析相对路径。

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

When you use 'getResource' on a Class, a relative path is resolved based on the package the Class is in. When you use 'getResource' on a ClassLoader, a relative path is resolved based on the root folder.

If you use an absolute path, both 'getResource' methods will start at the root folder.

不必了 2024-07-21 09:14:12

@吉安卡洛:
您可以尝试调用系统属性 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);

@GianCarlo:
You can try calling System property user.dir that will give you root of your java project and then do append this path to your relative path for example:

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);
隔纱相望 2024-07-21 09:14:12

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

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

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

For those using eclipse + maven. Say you try to access the file images/pic.jpg in src/main/resources. Doing it this way :

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

is perfectly correct, but may result in a null pointer exception. Seems like eclipse doesn't recognize the folders in the maven directory structure as source folders right away. By removing and the src/main/resources folder from the project's source folders list and putting it back (project>properties>java build path> source>remove/add Folder), I was able to solve this.

清风夜微凉 2024-07-21 09:14:12
resourcesloader.class.getClass()

可以细分为:

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

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

相反,您可能想要类似的内容:

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

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

resourcesloader.class.getClass()

Can be broken down to:

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

Which means you're trying to load the resource using a bootstrap class.

Instead you probably want something like:

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

If only javac warned about calling static methods on non-static contexts...

﹏雨一样淡蓝的深情 2024-07-21 09:14:12

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

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 读取文件。 不要使用字符串来标识文件的路径,因为如果路径中包含空格或某些非英文字母的字符,则会出现问题并且无法找到该文件。

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

In Order to obtain real path to the file you can try this:

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

Resourceloader is classname here.
"resources/repository/SSL-Key/cert.jks" is relative path to the file. If you had your guiclass in ./package1/java with rest of folder structure remaining, you would take "../resources/repository/SSL-Key/cert.jks" as relative path because of rules defining relative path.

This way you can read your file with BufferedReader. DO NOT USE THE STRING to identify the path to the file, because if you have spaces or some characters from not english alphabet in your path, you will get problems and the file will not be found.

BufferedReader bufferedReader = new BufferedReader(
                        new InputStreamReader(fileUrl.openStream()));
放赐 2024-07-21 09:14:12

下面的工作有效吗?

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

是否有原因无法指定包括包的完整路径?

Doe the following work?

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

Is there a reason you can't specify the full path including the package?

幸福不弃 2024-07-21 09:14:12

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

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

应该是同一个东西吗?

Going with the two answers as mentioned above. The first one

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

Should be one and same thing?

七禾 2024-07-21 09:14:12

我对 @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();

I made a small modification on @jonathan.cone's one liner ( by adding .getFile() ) to avoid null pointer exception, and setting the path to data directory. Here's what worked for me :

String realmID = new java.util.Scanner(new java.io.File(RandomDataGenerator.class.getClassLoader().getResource("data/aa-qa-id.csv").getFile().toString())).next();
动次打次papapa 2024-07-21 09:14:12

用这个:

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

Use this:

resourcesloader.class.getClassLoader().getResource("/path/to/file").**getPath();**
笔芯 2024-07-21 09:14:12

在所有操作系统上工作的稳定方法之一是获取 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;
}

One of the stable way to work across all OS would be toget 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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文