在我们编写Java的应用程序时,可能会用到一些配置文件,如config.properties,我们可以在配置文件中存储一些重要信息,例如服务器的IP地址,用户名和密码等信息。


在本篇文章当中,只是讨论如何获取到资源文件的路径,并不会对资源文件的内容进行读取。



1、资源目录:src目录和bin目录


在我们编写Java代码的过程当中,我们会把有关的资源文件(例如config.properties)放到src目录和src目录下的某个package中。


但有一点值得注意的是,虽然我们在放置资源文件的时候是在src目录下,但是当我们对资源文件进行读取的时候,却是在(与src同级的)bin目录下。


换句话说,当我们添加资源文件的时候,是在src目录下,但是当程序运行的时候,会将src目录下的资源复制到bin目录下,因此程序访问的资源文件是位于bin目录下的。


在进行代码访问之前,让我来做一些准备,准备三个文件。

第一个文件位于com.rk.io下的config.properties文件,其内容如下:

ServerIP=192.168.80.150
UserName=parentdirectory
Password=123456

第二个文件位于com.rk.io.property下的config.properties文件,其内容如下:

ServerIP=192.168.80.100
UserName=currentdirectory
Password=123456

第三个文件位于com.rk.io.property.subdirectory下的config.properties文件,其内容如下:

ServerIP=192.168.80.50
UserName=subdirectory
Password=123456




2、通过java.lang.Class类的getResource方法访问资源



2.1、以"/"为开头的访问路径的方式



2.1.1、访问第一个文件


代码如下:

package com.rk.io.property;

import java.net.URL;

public class PropertyClassParent
{

	public static void main(String[] args)
	{
		URL resourceURL = PropertyClassParent.class.getResource("/com/rk/io/config.properties");
		String fileName = resourceURL.getFile();
		System.out.println(fileName);
	}

}

输出结果:

/D:/rupeng/workspace/RK/bin/com/rk/io/config.properties



2.1.2、访问第二个文件


代码如下:

package com.rk.io.property;

import java.net.URL;

public class PropertyClassCurrent
{
	public static void main(String[] args)
	{
		URL resourceURL = PropertyClassCurrent.class.getResource("/com/rk/io/property/config.properties");
		String fileName = resourceURL.getFile();
		System.out.println(fileName);
	}
}


输出结果:

/D:/rupeng/workspace/RK/bin/com/rk/io/property/config.properties



2.1.3、访问第三个文件


代码如下:

package com.rk.io.property;

import java.net.URL;

public class PropertyClassSub
{

	public static void main(String[] args)
	{
		URL resourceURL = PropertyClassSub.class.getResource("/com/rk/io/property/subdirectory/config.properties");
		String fileName = resourceURL.getFile();
		System.out.println(fileName);
	}
}


输出结果:

/D:/rupeng/workspace/RK/bin/com/rk/io/property/subdirectory/config.properties



2.2、不以"/"开头的访问路径的方式



2.2.1、访问第一个文件


代码如下:

package com.rk.io.property;

import java.net.URL;

public class PropertyClassParent2
{

	public static void main(String[] args)
	{
		URL resourceURL = PropertyClassParent2.class.getResource("../config.properties");
		String fileName = resourceURL.getFile();
		System.out.println(fileName);
	}
}

输出结果:

/D:/rupeng/workspace/RK/bin/com/rk/io/config.properties



2.2.2、访问第二个文件


代码如下:

package com.rk.io.property;

import java.net.URL;

public class PropertyClassParent2
{

	public static void main(String[] args)
	{
		URL resourceURL = PropertyClassParent2.class.getResource("config.properties");
		String fileName = resourceURL.getFile();
		System.out.println(fileName);
	}
}


输出结果:

/D:/rupeng/workspace/RK/bin/com/rk/io/property/config.properties



2.2.3、访问第三个文件


代码如下:

package com.rk.io.property;

import java.net.URL;

public class PropertyClassSub2
{

	public static void main(String[] args)
	{
		URL resourceURL = PropertyClassSub2.class.getResource("subdirectory/config.properties");
		String fileName = resourceURL.getFile();
		System.out.println(fileName);
	}
}

输出结果:

/D:/rupeng/workspace/RK/bin/com/rk/io/property/subdirectory/config.properties



3、通过java.lang.ClassLoader的getResource方法访问资源


3.1、访问第一个文件


代码如下:

package com.rk.io.property;

import java.net.URL;

public class PropertyClassParent
{

	public static void main(String[] args)
	{
		URL resourceURL = PropertyClassParent.class.getClassLoader().getResource("com/rk/io/config.properties");
		String fileName = resourceURL.getFile();
		System.out.println(fileName);
	}
}

输出结果:

/D:/rupeng/workspace/RK/bin/com/rk/io/config.properties



3.2、访问第二个文件

代码如下:

package com.rk.io.property;

import java.net.URL;

public class PropertyClassCurrent
{
	public static void main(String[] args)
	{
		URL resourceURL = PropertyClassCurrent.class.getClassLoader().getResource("com/rk/io/property/config.properties");
		String fileName = resourceURL.getFile();
		System.out.println(fileName);
	}
}

输出结果:

/D:/rupeng/workspace/RK/bin/com/rk/io/property/config.properties



3.3、访问第三个文件


代码如下:

package com.rk.io.property;

import java.net.URL;

public class PropertyClassLoaderSub
{

	public static void main(String[] args)
	{
		URL resourceURL = PropertyClassLoaderSub.class.getClassLoader().getResource("com/rk/io/property/subdirectory/config.properties");
		String fileName = resourceURL.getFile();
		System.out.println(fileName);
	}
}

输出结果:

/D:/rupeng/workspace/RK/bin/com/rk/io/property/subdirectory/config.properties


4、对比java.lang.Class和java.lang.ClassLoader的getResource方法

对于java.lang.Class类的getResource方法,在传入的参数中:

如果只有一个"/config.properties",则表示bin目录下的config.properties文件;

如果输入"/com/rk/io/config.properties",则表示在bin目录下的com/rk/io内的config.propertiesy文件。

如果输入"config.properties",则表示与当前类的.class文件在同一目录当中的config.properties;

如果输入"../config.properties",则表示当前类的.class的父目录中的config.properties文件。


对于java.lang.ClassLoader的getResource方法,其有一段英文描述如下:

Finds the resource with the given name. A resource is some data (p_w_picpaths, audio, text, etc) that can be accessed by class code in a way that is independent of the location of the code. 


用这个方法,资源文件的位置和class code之间是彼此独立的(a resource is some data that can be accessed by class code in a way that is independent of the location of the code)