通常情况下我们可以提前写好一些properties文件存在在src目录下或者resources目录下,读取properties文件是需要经常用到的操作,这里来总结下几种不同的读取方式。
1.基于getResourceAsStream读取
这种方式的读取取决于properties文件和class文件存放的相对位置
-
Class.getResourceAsStream(String path) : path 不以’/'开头时默认是从此类所在的包下取资源,以’/'开头则是从ClassPath根下获取
-
Class.getClassLoader.getResourceAsStream(String path) :默认则是从ClassPath根下获取,path不能以’/'开头,最终是由ClassLoader获取资源
两种方式都是返回一个InputStream输入流,但存在细微的差别,主要在path上
1.1 Class.getResourceAsStream
Class.getResourceAsStream默认是读取与该类文件相同包下的文件,否则会返回null,实际上是没找到properties文件;但是可以使用相对路径来读取。
目录结构如下:

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.Set;
public class ReadProperties {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
// 使用ClassLoader加载properties配置文件生成对应的输入流
InputStream in1 = ReadProperties.class.getResourceAsStream("a.properties");
// InputStream in2= ReadProperties.class.getClassLoader().getResourceAsStream("property/a.properties");
// 使用properties对象加载输入流
properties.load(in1);
Set<String> set = properties.stringPropertyNames();
for (String key: set) {
String value = properties.getProperty(key);
System.out.println(key + ":" + value);
}
}
}
ReadProperties类文件和a.properties文件位置在同一个包下,因此path="a.properties",如果
a.properties文件在config包下,那么path相应做出改变,此时path="config/a.properties",其他可以类推,"/"代表根目录,即src目录。
1.2 Class.getClassLoader.getResourceAsStream
Class.getClassLoader.getResourceAsStream默认是从根目录下读取,所以刚才直接读path="a.properties"会报错,因为src目录下没有该文件,所以path="property/a.properties",这里需要注意的是path中不能使用"/",因为classloader的路径已经是根目录,使用"/"会报空指针错误。
提示: 该方法可以读取resource目录下的文件,path="a.properties"就可以,但是上面Class.getResourceAsStream方法不行
这种方法的优点是动态读取路径,缺点是读取的范围有限
2.基于InputStream
InputStream in= new FileInputStream(new File("E:\\JavaProject\\JavaSE\\Javacore\\src\\property\\a.properties"));
// 使用properties对象加载输入流
properties.load(in);
这种方法读取需要完整的路径,优点是可以读取任意路径下的文件,缺点是不太灵活
3.基于ResourceBundle类来读取
ResourceBundle rb = ResourceBundle.getBundle("b"); //读取resources目录下的b.properties
//ResourceBundle rb = ResourceBundle.getBundle("property/a"); 读取property目录下的a.properties
for(String key : rb.keySet()){
String value = rb.getString(key);
System.out.println(key + ":" + value);
}
ResourceBundle rb = ResourceBundle.getBundle("b") //不需要指定文件名的后缀
ResourceBundle.getBundle的路径访问和 Class.getClassLoader.getResourceAsStream类似,默认从根目录下读取,也可以读取resources目录下的文件。
完整代码
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Set;
public class ReadProperties {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
// 使用ClassLoader加载properties配置文件生成对应的输入流
// InputStream in = ReadProperties.class.getResourceAsStream("a.properties");
InputStream in= ReadProperties.class.getClassLoader().getResourceAsStream("a.properties");
// InputStream in= new FileInputStream(new File("E:\\JavaProject\\JavaSE\\Javacore\\src\\property\\a.properties"));
// 使用properties对象加载输入流
properties.load(in);
Set<String> set = properties.stringPropertyNames();
for (String key: set) {
String value = properties.getProperty(key);
System.out.println(key + ":" + value);
}
System.out.println("<------------>");
ResourceBundle rb = ResourceBundle.getBundle("a");
for(String key : rb.keySet()){
String value = rb.getString(key);
System.out.println(key + ":" + value);
}
}
}
网友评论