前言

在Spring的时候,通过XML配置文件的方式进行配置数据库连接池的时候,就会使用==context:property-placeholder==标签进行读取,在这里呢,也是通过Java几种比较基础的方式来读取Properties文件。

在开始之前,说下目前比价常用的几种方式:
1. 使用java.util.Properties类,可以使用它的load方法加载inputStream字节流。
2. 使用java.util.ResourceBundle类来读取。

使用Properties类

Properties类继承自Hashtable,而Hashtable是实现了Map接口的,所以对Properties类的操作和Map有些相似。

使用Properties来加载.properties文件的主要关键是在于load方法。而load方法需要的是InputStream流。

这里比较常用的流的获取有以下几种:

  1. 使用当前类的ClassLoader()的getResourceAsStream(),getResourcesAsStream返回一个InputStream。
  2. 使用ClassLoader类的getSystemResourceAsStream(),该方法也返回一个InputStream。
  3. 使用文件输入流的方式。

具体示例如下,为了方便,我直接使用的log4j.properties。

/**
	 * 单独抽取的方法,用户检测能否正确操纵Properties
	 *
	 * @param inputStream
	 * @throws IOException 为了排版美观,直接抛出异常
	 */
	public void printKeyValue(InputStream inputStream) throws IOException {
		Properties properties = new Properties();
		properties.load(inputStream);
		Set<Object> keys = properties.keySet();
		for (Object key : keys) {
			System.out.println(key + " = " + properties.get(key));
		}
	}

	/***
	 * 从当前的类加载器的getResourcesAsStream来获取.
	 * 使用Class.class.getClassLoader().getResourcesAsStream()进行获取的时候,所填写的路径只能为项目的绝对路径
	 * @throws IOException
	 */
	@Test
	public void getPropertiesFromResourceAsStream() throws IOException {
		InputStream resourceAsStream = PropertiesUtils.class.getClassLoader().getResourceAsStream("com/dimple/getproperityfile/mylog4j.properties");
		printKeyValue(resourceAsStream);
	}

	/***
	 * 从文件中获取,使用InputStream字节
	 * 主要是需要加上src这个文件夹名。。。路径配置需要精确到绝对地址级别
	 * 什么意思,就是如果这个mylog4j文件在com/dimple/getproperityfile/mylog4j.properties下,而这个com文件夹
	 * 又在src目录下,那么写的时候需要加上这个src,这样的相对路径+项目地址能够构成一个完整的访问地址即可
	 * @throws IOException
	 */
	@Test
	public void getPropertiesFromFile() throws IOException {
		InputStream inputStream = new FileInputStream(new File("src/com/dimple/getproperityfile/mylog4j.properties"));
		printKeyValue(inputStream);
	}

	/**
	 * 使用Class类的getSystemResourceAsStream方法
	 * 和使用当前类的ClassLoader是一样的
	 *
	 * @throws IOException
	 */
	@Test
	public void getPropertiesFromClassLoader() throws IOException {
		InputStream systemResourceAsStream = ClassLoader.getSystemResourceAsStream("com/dimple/getproperityfile/mylog4j.properties");
		printKeyValue(systemResourceAsStream);
	}

使用ResourceBundle类

使用ResourcesBundle类也两种方法可以读取到配置文件

  1. 使用类ResourcesBundle的getBundle方法加载properties文件。
  2. 使用其派生类PropertyResourceBundle(),通过传入一个InputStream来读取数据。

代码如下:

/***
	 * 使用java.util.ResourceBundle类来加载properties文件,注意不需要带上后缀名。
	 */
	@Test
	public void getPropertiesFromResourceBundle() {
		ResourceBundle resourceBundle = ResourceBundle.getBundle("com/dimple/getproperityfile/mylog4j");
		Enumeration<String> keys = resourceBundle.getKeys();
		while (keys.hasMoreElements()) {
			String s = keys.nextElement();
			System.out.println(s + " = " + resourceBundle.getString(s));
		}
	}

	/**
	 * 使用InputStream流来进行操作ResourceBundle,获取流的方式由以上几种。
	 * @throws IOException
	 */
	@Test
	public void getPropertiesFromResourceBundleInputStream() throws IOException {
		InputStream systemResourceAsStream = ClassLoader.getSystemResourceAsStream("com/dimple/getproperityfile/mylog4j.properties");
		ResourceBundle resourceBundle = new PropertyResourceBundle(systemResourceAsStream);
		Enumeration<String> keys = resourceBundle.getKeys();
		while (keys.hasMoreElements()) {
			String s = keys.nextElement();
			System.out.println(s + " = " + resourceBundle.getString(s));
		}
	}

总结

以上代码的的方法具体有什么用已经表明了,遇到的问题已经不是代码问题了。而是路径。对于这个路径,相对路径,绝对路径,项目路径,这个路径确实让我有些头痛,在File的Test代码哪里,文件路径近乎是我试出来的。当然读者可能会说,直接拿鼠标去点,能点进去的就是对的,但是,在File那里,我没有加src,是可以点击去的,但是项目报错提示FileNotFound,加上src就能正常访问,但是点不进去。这个原因是因为IDEA这里,有一个工程路径的说法,工程路径并不包含src,而代码是写在src下的,所以导致最后的绝对路径不可达,所以报错。