java项目中,经常需要将资源文件打包放在项目中,然后在项目中去读取对应的文件。
InputStream inputStream =this.getServletContext().getResourceAsStream("/WEB-INF/classes/error.xml");
(2)先读取文件,再读取为流,获取路径的方式和上面是类似的
String path =this.getServletContext().getRealPath("/WEB-INF/classes/error.xml");
InputStream inputStream = newFileInputStream(path);
以下面的一个项目为例,项目的目录结构如下:
├── conf
│ └── krb5.conf
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ ├── resources
│ │ ├── thrift
│ │ └── thrift-java
│ └── test
│ └── java
└── thriftdemo.iml
这是一个maven项目,maven项目默认的结构中,resource位于main目录下面。现在我们希望读取到外面conf目录下的krb5.conf配置文件,该怎么办呢。
为了达到读取并解析krb5.conf的目的,我们首先写了一段简单的测试代码。
@Test
publicvoidt1() {
String path =Demo.class.getClassLoader().getResource("").getPath();
System.out.println(path);
String filestr = path + "/conf/krb5.conf";
try {
BufferedReader br = new BufferedReader(new FileReader(newFile(filestr)));
while(br.readLine() != null) {
System.out.println(br.readLine());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
对于这段代码,首先我们需要清楚的一点是:ClassLoader.getResource方法的入参必须是从根目录开始查找,这里根目录就是target里的classes!
如果我们代码正常运行起来以后,打印出来的路径为:
/xxx/.../target/classes/
在使用ClassLoader.getResource的时候,注意查找必须是基于根目录,例如在Intellij中就是target/classes。并且目录结构也需要写对,不能以”/”开头。
如果我们不使用ClassLoader.getResource的方式,而是用Class.getResource的方法,也能定位到资源文件。代码如下:
@Test
public void t2() {
String path = Demo1.class.getResource("").getPath();
System.out.println(path);
String path2 = Demo1.class.getResource("/").getPath();
System.out.println(path2);
}
看一下代码的输出结果:
/xxx/.../target/classes/edu/bit/files/
/xxx/.../target/classes/
需要注意的就是,如果使用Class.getResource方法,入参为空的时候,是当前.class文件的路径;而当入参为”/”的时候,是从根目录开始查找!
我们希望最终打包的结果为如下的结构:
classes/
├── conf
│ └── krb5.conf
├── demo.thrift
└── edu
└── bit
构建Maven项目的时候,如果没有进行特殊的配置,Maven会按照标准的目录结构查找和处理各种类型文件。
maven-resources-plugin
2.5
copy-conf
process-sources
copy-resources
${basedir}/target/classes/conf
${project.basedir}/conf
**/*.xml
**/*.conf
其中,directory标签配置的是resource文件的源路径,outputDirectory配置的是resource文件的输出路径。因为我们想将资源文件放置在classes的conf目录下面,所以按照上面的配置方式即可。
${basedir}/conf
${basedir}/target/classes/conf
在resources节点里做上面的配置,也能达到上面同样的效果!