写点什么

Spring 之资源读取

作者:andy
  • 2022-10-27
    北京
  • 本文字数:2059 字

    阅读完需:约 7 分钟

一、资源文件的读取问题


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 文件。


用户头像

andy

关注

还未添加个人签名 2019-11-21 加入

还未添加个人简介

评论

发布
暂无评论
Spring之资源读取_andy_InfoQ写作社区