一、资源文件的读取问题
Java 平台提供了原生的资源读取操作工具,即 Java IO 工具类。其中,以 InputStream 和 OutputStream 对文件进行字节流的读取操作类。但是,使用字节流操作类编写代码过于麻烦。随后推出了 PrintStream、Scanner 类对资源文件读取操作的提升。随着发展,在针对网络资源、CLASSPATH 路径下的资源以及*.jar 包里的文件操作上,显现出了自身的不足。
spring 根据以上暴露出的问题,对资源操作进行了改进,提供了专门处理资源的接口 org.springframework.core.io.Resource(org.springframework.core.io.InputStreamSource 的子接口),在接口的帮助下,对资源的操作能力大大提高。
接口只是定义了处理事物的能力,具体的实现则由子类完成。spring 提供了以下 Resource 接口的子类:ByteArrayResource(内存读取)、ClassPathResource(类路径读取)、FileSystemResource(文件读取)、UrlResource(url 读取)、ServletContextResource(web 上下文读取)等等。
二、读取不同资源
根本上说,Resource 接口除了通过不同子类实现不同资源读取,其他的方面(如操作方法)则相同。
2.1、内存操作流
public static void readAndDisplayByteArray(String str) throws IOException{
Resource resource = new ByteArrayResource(str.getBytes());
if(resource.exists()){
Scanner scanner = new Scanner(resource.getInputStream());
if(scanner.hasNext()){
logger.info(scanner.nextLine());
}
scanner.close();
}
}
复制代码
2.2、文件操作
public static void readFile(String filePath) throws IOException{
Resource resource = new FileSystemResource(filePath);
if(resource.exists()){
Scanner scanner = new Scanner(resource.getInputStream());
while(scanner.hasNext()){
logger.info(scanner.nextLine());
}
scanner.close();
}
}
复制代码
2.3、CLASSPATH 下的文件读取
public static void readFileFromClassPath(String fileNameOrRelativeFilePath) throws IOException{
Resource resource = new ClassPathResource(fileNameOrRelativeFilePath);
if(resource.exists()){
Scanner scanner = new Scanner(resource.getInputStream());
while(scanner.hasNext()){
logger.info(scanner.nextLine());
}
scanner.close();
}
}
复制代码
三、ResourceLoader 接口
根据以上信息,对于 Resource 接口的子类,都需要通过关键字 new 进行实例化之后,才可调用方法进行资源读取,这样无形中增加强引用,而且还必须针对不同的资源需求选择不同的子类,这样显得比较麻烦,因此,spring 提供了一个更加简化的接口 org.springframework.core.io.ResourceLoader,该接口可通过子类 org.springframework.core.io.DefaultResourceLoader 实例化。接口提供了 Resource getResource(String location)方法,根据提供了参数格式,处理不同类型的资源。
字符串格式说明如下:
读取文件系统资源:file:路径
读取网络资源(可下载资源):http://路径
读取 CLASSPATH 路径下的资源:classpath:路径
示例:
ResourceLoader resourceLoader = new DefaultResourceLoader();
Resource resource = resourceLoader.getResource("字符串文件格式");
复制代码
注意:网络资源这里是可下载资源,其他的资源读取不了,比如页面
四、Resource 资源注入
根据 spring 的依赖注入,通过配置 resource,注入实例对象,从而达到消除硬编码,又可灵活修改读取文件的路径。其本质是隐藏了 ResourceLoader 接口,然后对 Resource 接口进行注入。
4.1、读取 CLASSPATH 资源
Java 代码:
package org.fuys.own.test;
import org.springframework.core.io.Resource;
public class SpringResourceTest {
private Resource resource;
}
复制代码
配置文件信息:
<bean id="springResourceTest" class="org.fuys.own.test.SpringResourceTest">
<property name="resource" value="classpath:log4j.properties"/>
</bean>
复制代码
4.2、多个资源的配置
Java 代码:
package org.fuys.own.test;
import org.springframework.core.io.Resource;
public class SpringResourceTest {
private Resource[] resources;
}
复制代码
配置文件信息:
<bean id="springResourceTest" class="org.fuys.own.test.SpringResourceTest">
<property name="resources">
<array>
<value>http://www.springframework.org/schema/beans/spring-beans.xsd</value>
<value>classpath:applicationContext.xml</value>
</array>
</property>
</bean>
复制代码
五、通配符
Resource 提供了通配符,以解决项目中复杂文件的定位问题,包括*.jar 包中的资源(如 license.txt)。以下支持三种通配符:
“?”,匹配任意一个字符,如 license-?,则会查询出 licence-1、licence-2 等文件;
“*”,匹配任意多位字符,如 license*,则会查询出 license-1、licenseX 文件,也如/a/*/license,则查询出 a 目录下的一级目录下的子目录中的所有 license 文件;
“**”,匹配任意多级目录的字符串内容,如 a/**/license,则查询出 a 目录下的所有目录下的 license 文件。
评论