fuk*_*uri 7 java packages directory-structure getresource
我没有长时间使用java,所以我不确定还有什么要寻找的.我希望有人可以指出我正确的方向.
目标: 我想使用查找表,存储为文本文件.但我不想使用绝对路径,因为最后我想打包一个版本并能够从任何位置调用它(文本文件将包含在打包版本中).
当前设置: 我将文本文件放在一个名为"resources"的文件夹中(因为从阅读有关java的教程,我得到了印象,这是我应该把它用来维护一个更好的结构化项目).
在根包文件夹中,我有一个类(MainClass.java),它在子包中调用另一个类(LookUpClass.java).文件夹设置如下:
我写了一个方法LookUpClass.java,就是从资源中的查找表中检索某一行.为了检索文件并读出某一行,我用了
// Gets respective line from LUT
private static String getLineFromLUT(int line) {
URL url = LookUpClass.class.getClass().getResource("/LookUpTables/LookUpTable1.txt");
File file = new File(url.toURI());
BufferedReader br = new BufferedReader(new FileReader(file));
for (int i = 0; i < line; ++i)
br.readLine();
return br.readLine;
}
Run Code Online (Sandbox Code Playgroud)
在我的项目结构中,"java"文件夹被标记为"source",而"resources"被标记为"resources".
我的测试设置非常简单:
public static void main(String[] args) throws URISyntaxException, IOException {
String c = LookUpClass.getLineFromLUT(5);
System.out.println("Color of line 5: " + c);
}
Run Code Online (Sandbox Code Playgroud)
输出:
Color of line 5: 0 0 38
Run Code Online (Sandbox Code Playgroud)
(哪个是对的.)
我添加了完全相同的行PlotterClass.java,它也工作正常.
问题:
现在,如果我尝试相同,MainClass.java我得到一个错误,url为null.似乎无法找到资源/资源文件夹.
我已经阅读了SO上的各种帖子,并尝试了几个提议的解决方案,到目前为止都失败了:
LookUpClass.class.getClassLoader().getResource("/LookUpTables/LookUpTable1.txt")from MainClass.java和LookUpClass.javafail 两个调用(url为null).Class c = LookUpClass.class.getClass();,在调试模式c中是"class.java.lang.Class".我期待像"main.package.com.subpackage.LookUpClass"这样的东西.getResourceAsStream(),但我不明白如何获得我的(例如)第5行,所以我放弃了它.如果它解决了我的问题,我愿意读这个.我不知道如何解决这个问题.而且我意识到,在这一点上,我只是在尝试一些事情,甚至不理解为什么它可以或不可行.对我来说,它似乎LookUpClass.java只是从不同的位置运行MainClass.java.但"资源"文件夹和相应的文本文件位置永远不会改变.如何在一个案例中找到该文件,而在另一个案例中却找不到?
Maven 有一个标准的目录布局。该目录src/main/resources适用于此类应用程序资源。将您的文本文件放入其中。
现在,您基本上有两个选择来准确放置文件:
一个示例是表示 GUI 元素(面板)的类,该元素还需要显示一些图像。
在这种情况下,将资源文件放入与相应类相同的目录(包)中。例如,对于名为的类,your.pkg.YourClass将资源文件放入目录中your/pkg:
src/main
+-- java/
| +-- your/pkg/
| | +-- YourClass.java
+-- resources/
+-- your/pkg/
+-- resource-file.txt
Run Code Online (Sandbox Code Playgroud)
现在,您可以通过相应的类加载资源。在类中,your.pkg.YourClass您有以下用于加载的代码片段:
String resource = "resource-file.txt"; // the "file name" without any package or directory
Class<?> clazz = this.getClass(); // or YourClass.class
URL resourceUrl = clazz.getResource(resource);
if (resourceUrl != null) {
try (InputStream input = resourceUrl.openStream()) {
// load the resource here from the input stream
}
}
Run Code Online (Sandbox Code Playgroud)
注意:您还可以通过类的类加载器加载资源:
String resource = "your/pkg/resource-file.txt";
ClassLoader loader = this.getClass().getClassLoader(); // or YourClass.class.getClassLoader()
URL resourceUrl = loader.getResource(resource);
if (resourceUrl != null) {
try (InputStream input = resourceUrl.openStream()) {
// load the resource here from the input stream
}
}
Run Code Online (Sandbox Code Playgroud)
选择您觉得更方便的。
在这种情况下,只需将资源直接放入src/main/resources目录或适当的子目录中即可。让我们看一下查找文件的示例:
src/main/resources/
+-- LookupTables/
+-- LookUpTable1.txt
Run Code Online (Sandbox Code Playgroud)
然后,您必须通过类加载器加载资源,使用当前线程的上下文类加载器或应用程序类加载器(无论哪种更合适 - 如果感兴趣,请搜索有关此问题的文章)。我将向您展示两种方法:
String resource = "LookupTables/LookUpTable1.txt";
ClassLoader ctxLoader = Thread.currentThread().getContextClassLoader();
ClassLoader sysLoader = ClassLoader.getSystemClassLoader();
URL resourceUrl = ctxLoader.getResource(resource); // or sysLoader.getResource(resource)
if (resourceUrl != null) {
try (InputStream input = resourceUrl.openStream()) {
// load the resource here from the input stream
}
}
Run Code Online (Sandbox Code Playgroud)
作为第一个建议,使用当前线程的上下文类加载器。在独立应用程序中,这将是系统类加载器或将系统类加载器作为父级。(这些类加载器之间的区别对于也加载资源的库来说变得很重要。)
您应该始终使用类加载器来加载资源。通过这种方式,您可以使加载独立于位置(只需注意启动应用程序时文件位于类路径内),并且您可以将整个应用程序打包到仍然可以找到资源的 JAR 文件中。
| 归档时间: |
|
| 查看次数: |
1683 次 |
| 最近记录: |