章
目
录
学习在Java应用程序中从resources资源文件夹中读取文件。我们将学会如何读取位于jar文件内部和外部的文件。jar文件外部的文件可能存在于war文件或开发环境中的Eclipse项目中。
1.将文件打包到资源文件夹中
资源文件夹属于Maven项目结构,我们将与应用程序相关的配置和数据文件放置在其中。该文件夹的位置可以是“src/main/resources”和“src/test/resources”。
- 在将应用程序打包为jar文件时,位于’/resources’文件夹中的文件会被复制到根目录’target/classes’文件夹中。在这种情况下,文件位置位于一个像jar-filename.jar/!filename.txt这样的压缩存档内。我们应直接将此文件读取为InputStream。
- 在将应用程序打包为war文件时,位于’/resources’文件夹中的文件会被复制到根目录’/target/app-name’文件夹中。在应用服务器中部署后,war文件会被解压缩到服务器工作目录中。因此,在这种情况下,我们是在读取位于压缩存档之外的文件,因此可以使用相对路径引用该文件。我们可以使用File实例引用此文件,并使用适当的方法读取文件内容。
在给定的示例中,我们读取了/resources文件夹中的两个文件。第一个文件/demo.txt位于/resources文件夹的根目录下。第二个文件/data/demo.txt位于/resources文件夹中的嵌套文件夹/data内。
2.以.jar文件打包的资源
2.1. 使用ClassLoader.getResourceAsStream()
使用getResourceAsStream()方法在从jar文件内部读取文件时获取InputStream。始终在ClassLoader实例上使用此方法。
此代码也适用于开发环境。
private InputStream getFileAsIOStream(final String fileName)
{
InputStream ioStream = this.getClass()
.getClassLoader()
.getResourceAsStream(fileName);
if (ioStream == null) {
throw new IllegalArgumentException(fileName + " is not found");
}
return ioStream;
}
2.2. 完整示例
一旦我们获得了InputStream引用,就可以使用它来读取文件内容或将其传递给任何资源处理程序类。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class ReadFileFromResourcesUsingGetResourceAsStream
{
public static void main(final String[] args) throws IOException
{
//创建实例以避免静态成员方法
ReadFileFromResourcesUsingGetResourceAsStream instance
= new ReadFileFromResourcesUsingGetResourceAsStream();
InputStream is = instance.getFileAsIOStream("demo.txt");
instance.printFileContent(is);
is = instance.getFileAsIOStream("data/demo.txt");
instance.printFileContent(is);
}
private InputStream getFileAsIOStream(final String fileName)
{
InputStream ioStream = this.getClass()
.getClassLoader()
.getResourceAsStream(fileName);
if (ioStream == null) {
throw new IllegalArgumentException(fileName + " is not found");
}
return ioStream;
}
private void printFileContent(InputStream is) throws IOException
{
try (InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);)
{
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
is.close();
}
}
}
2.3. 如何测试代码
要测试上述代码,请使用’mvn clean package’命令将应用程序打包为jar文件。还要为maven-jar-plugin提供’mainClass’属性,并将其值设置为包含main()方法和测试代码的类。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.howtodoinjava.io.ReadFileFromResourcesUsingGetResourceAsStream</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
现在,从控制台运行main()方法。
mvn clean package
java -jar target\app-build-name.jar
Content from demo.txt
Content from data/demo.txt
3.以.war文件打包的资源
3.1. 使用ClassLoader.getResource()
使用getResource()方法在从war文件内部读取文件时获取File实例。建议在ClassLoader实例上使用此方法。
private File getResourceFile(final String fileName)
{
URL url = this.getClass()
.getClassLoader()
.getResource(fileName);
if(url == null) {
throw new IllegalArgumentException(fileName + " is not found 1");
}
File file = new File(url.getFile());
return file;
}
3.2. 完整示例
现在使用File引用来读取文件内容。
package com.howtodoinjava.io;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.file.Files;
public class ReadFileFromResourcesUsingGetResource {
public static void main(final String[] args) throws IOException
{
//创建实例以避免静态成员方法
ReadFileFromResourcesUsingGetResource instance
= new ReadFileFromResourcesUsingGetResource();
File file = instance.getResourceFile("demo.txt");
instance.printFileContent(file);
file = instance.getResourceFile("data/demo.txt");
instance.printFileContent(file);
}
private File getResourceFile(final String fileName)
{
URL url = this.getClass()
.getClassLoader()
.getResource(fileName);
if(url == null) {
throw new IllegalArgumentException(fileName + " is not found 1");
}
File file = new File(url.getFile());
return file;
}
private void printFileContent(File file) throws IOException
{
String content = new String(Files.readAllBytes(file.toPath()));
System.out.println(content);
}
private void printFileContent(InputStream is) throws IOException
{
try (InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);)
{
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
is.close();
}
}
}
3.3. 如何测试代码
要测试上述代码,请使用mvn clean package命令将应用程序打包为war文件。使用maven-resources-plugin插件将文件从resources文件夹复制到war文件存档的根目录中。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<overwrite>true</overwrite>
<outputDirectory>${project.build.directory}/${project.artifactId}-${project.version}/</outputDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
现在,从控制台运行main方法。不要忘记将类添加到类路径中。
mvn clean package
java -classpath "classes/." com.howtodoinjava.io.ReadFileFromResourcesUsingGetResource
Content from demo.txt
Content from data/demo.txt
4.在Spring /Boot应用程序中使用ResourceUtils
如果应用程序是Spring WebMVC或Spring Boot应用程序,那么我们可以利用org.springframework.util.ResourceUtils类。
File file = ResourceUtils.getFile("classpath:demo.txt")
//File is found
System.out.println("File Found : " + file.exists());
//Read File Content
String content = new String(Files.readAllBytes(file.toPath()));
System.out.println(content);