我知道这个问题已经被问过好几次了,但我仍然无法通过这些解决方案解决这个问题。
我有一个maven项目。以及位于
consumer/src/main/java
中的一个Config.java 文件。内容如下:
import java.util.Properties;
public class Config {
Properties configFile;
public Config() {
configFile = new Properties();
try {
configFile.load(this.getClass().getClassLoader().
getResourceAsStream("property_table.config.txt"));
} catch(Exception e) {
e.printStackTrace();
}
}
public String getProperty(String key) {
String value = this.configFile.getProperty(key);
return value;
}
public static void main(String[] args) {
Config config = new Config();
System.out.println("URL: " + config.getProperty("URL"));
System.out.println("PASSWORD: " + config.getProperty("PASSWORD"));
}
}
我不断得到
nullpointer exception
。我知道那是因为它找不到文件property_table.config.txt
。
起初我把
property_table_config.txt
文件和Config.java文件放在同一个文件夹(consumer/src/main/java/
)。并尝试使用 /property_table_config.txt
和“property_table_config.txt”。它们都不起作用。
然后我尝试使用绝对路径,但没有用。并尝试使用
/main/java/property_table_config
,也没有用。
然后我看到了这个解决方案:https://stackoverflow.com/a/2103625/8159477。 所以我创建了一个名为资源的目录并将其放在主文件夹下(即文件夹的路径是
consumer/src/main/resources
,并在config
下创建一个子文件夹resources
。将property_table_config.txt
文件放在那里后,我改变了代码如下:
configFile.load(this.getClass().getClassLoader().getResourceAsStream("/config/property_table.config.txt"));
但这仍然没有用。任何人都可以对此给出一些提示吗?任何建议将不胜感激!
根据
Class.getResourceAsStream
:
这个方法委托给这个对象的类加载器。如果此对象由引导类加载器加载,则该方法委托给 ClassLoader.getSystemResourceAsStream。
在委托之前,绝对资源名称是使用以下算法从给定的资源名称构造的:
- 如果名称以“/”(“\u002f”)开头,则资源的绝对名称是“/”之后的名称部分。
- 否则,绝对名称的形式如下:
modified_package_name/name
其中 modified_package_name 是这个对象的包名,用 '/' 代替 '.' ('\u002e').
这就是我对评论的理解:
ClassLoader.getResourceAsStream
,从包根发送绝对路径,但省略第一个/
.Class.getResourceAsStream
,发送相对于当前Class
对象的路径(并且该方法将考虑包),或者从包根发送绝对路径,以/
开始。但除此之外,您还需要了解您的构建系统。用maven,资源文件存放在
src/main/resources
.下
因此,对于您的情况,我认为进行以下更改应该可以解决问题:
将文件放入
src/main/resources
.
将代码更改为
this.getClass()
.getResourceAsStream("/property_table.config.txt")
//or `Config.class.getResource...
或者,使用
this.getClass().getClassLoader()
.getResourceAsStream("property_table.config.txt")`
我用类似的设置试过这个,它按预期工作。
ClassLoader().getResourceAsStream()
仅在类路径中查找文件。
您需要的是将配置文件放在类路径中的目录中。
所以,你有选择:
当您从命令行运行 java 应用程序时,您可以在 -cp 参数或 CLASSPATH 系统变量中设置目录路径。重点是:您需要从中获取配置文件的目录必须在类路径中 - 而不是文件。 (例如,如果文件位置是
c:\my_projects\test-project\config\my_config.properties
并且 c:\my_projects\test-project\
在类路径中,那么 getResourceAsStream
调用将是 ClassLoader().getResourceAsStream("config/my_config.properties")
您可以将文件打包成 jar 文件,jar 文件的根目录是
getResourceAsStream("config/my_config.properties")
如果您的 Maven 项目是一个 jar 项目,您需要使用 Maven 资源插件将其他资源放入 jar。
顺便说一句:Maven 不会将任何内容从 src/main/java/ 目录放入 jar 文件(如果您没有为资源插件明确指定它)
如果你在 Maven 项目中使用像 Eclipse 这样的 IDE,src/main/resources 是构建类路径的一部分。仔细检查它是否存在,如果不存在 - 执行“更新 Maven 项目”或手动添加它。
只有当您在 IDE 中运行项目而不是从独立的 Jar 文件运行项目时,ClassLoader 才会从 src/main/resources 文件夹中看到您的属性文件——如果您没有打包文件或在类路径中提供位置。
嗨你能试试这个吗
String dirBase = new ClassPathResource("property_table.config.txt").getURI().getPath().replace("property_table.config.txt", "");
你能试试下面的代码吗?
Config.class.getResourceAsStream("property_table.config.txt")
更新: 这是我试过的代码。
package test;
import java.util.Properties;
public class Config
{
Properties configFile;
public Config()
{
configFile = new Properties();
try
{
configFile.load(Config.class.getResourceAsStream("property_table.config.txt"));
}
catch (Exception e)
{
e.printStackTrace();
}
}
public String getProperty(String key)
{
String value = this.configFile.getProperty(key);
return value;
}
public static void main(String[] args)
{
Config config = new Config();
System.out.println("URL: " + config.getProperty("URL"));
System.out.println("PASSWORD: " + config.getProperty("PASSWORD"));
}
}
我将 property_table.config.txt 文件放在测试包中,它起作用了。