通过Spring Resource接口获取资源

利用spring中的FileCopyUtils.copy()复制文件 package com.controller; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import org.springframework.core.io.ClassPat 阅读详情

通过Spring Resource接口获取资源

目录

1       Resource简介

2       通过ResourceLoader获取资源

3       在bean中获取Resource的方式

 

1       Resource简介

       在Spring内部,针对于资源文件有一个统一的接口Resource表示。其主要实现类有ClassPathResource、FileSystemResource、UrlResource、ByteArrayResource、ServletContextResource和InputStreamResource。Resource接口中主要定义有以下方法:

l  exists():用于判断对应的资源是否真的存在。

l  isReadable():用于判断对应资源的内容是否可读。需要注意的是当其结果为true的时候,其内容未必真的可读,但如果返回false,则其内容必定不可读。

l  isOpen():用于判断当前资源是否代表一个已打开的输入流,如果结果为true,则表示当前资源的输入流不可多次读取,而且在读取以后需要对它进行关闭,以防止内存泄露。该方法主要针对于InputStreamResource,实现类中只有它的返回结果为true,其他都为false。

l  getURL():返回当前资源对应的URL。如果当前资源不能解析为一个URL则会抛出异常。如ByteArrayResource就不能解析为一个URL。

l  getFile():返回当前资源对应的File。如果当前资源不能以绝对路径解析为一个File则会抛出异常。如ByteArrayResource就不能解析为一个File。

l  getInputStream():获取当前资源代表的输入流。除了InputStreamResource以外,其它Resource实现类每次调用getInputStream()方法都将返回一个全新的InputStream。

 

       ClassPathResource可用来获取类路径下的资源文件。假设我们有一个资源文件test.txt在类路径下,我们就可以通过给定对应资源文件在类路径下的路径path来获取它,new ClassPathResource(“test.txt”)。

       FileSystemResource可用来获取文件系统里面的资源。我们可以通过对应资源文件的文件路径来构建一个FileSystemResource。FileSystemResource还可以往对应的资源文件里面写内容,当然前提是当前资源文件是可写的,这可以通过其isWritable()方法来判断。FileSystemResource对外开放了对应资源文件的输出流,可以通过getOutputStream()方法获取到。

       UrlResource可用来代表URL对应的资源,它对URL做了一个简单的封装。通过给定一个URL地址,我们就能构建一个UrlResource。

       ByteArrayResource是针对于字节数组封装的资源,它的构建需要一个字节数组。

       ServletContextResource是针对于ServletContext封装的资源,用于访问ServletContext环境下的资源。ServletContextResource持有一个ServletContext的引用,其底层是通过ServletContext的getResource()方法和getResourceAsStream()方法来获取资源的。

       InputStreamResource是针对于输入流封装的资源,它的构建需要一个输入流。

Java代码  收藏代码
  1.    
  2. public class ResourceTest {  
  3.    
  4.    /** 
  5.     * ClassPathResource可以用来获取类路径下的资源 
  6.     * @throws IOException 
  7.     */  
  8.    @Test  
  9.    public void testClassPath() throws IOException {  
  10.       Resource resource = new ClassPathResource("test.txt");  
  11.       String fileName = resource.getFilename();  
  12.       System.out.println(fileName);  
  13. //    resource.getFile();   //获取资源对应的文件  
  14. //    resource.getURL(); //获取资源对应的URL  
  15.       if (resource.isReadable()) {  
  16.          //每次都会打开一个新的流  
  17.          InputStream is = resource.getInputStream();  
  18.          this.printContent(is);  
  19.       }  
  20.    }  
  21.     
  22.    /** 
  23.     * FileSystemResource可以用来获取文件系统里面的资源,对于FileSystemResource而言我们 
  24.     * 可以获取到其对应的输出流。 
  25.     * @throws IOException 
  26.     */  
  27.    @Test  
  28.    public void testFileSystem() throws IOException {  
  29.       FileSystemResource resource = new FileSystemResource("D:\\test.txt");  
  30.       if (resource.isReadable()) {  
  31.          //FileInputStream  
  32.          printContent(resource.getInputStream());  
  33.       }  
  34.       if (resource.isWritable()) {  
  35.          //每次都会获取到一个新的输出流  
  36.          OutputStream os = resource.getOutputStream();  
  37.          BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));  
  38.          bw.write("你好,中国!");  
  39.          bw.flush();  
  40.          if (os != null) {  
  41.             os.close();  
  42.          }  
  43.          if (bw != null) {  
  44.             bw.close();  
  45.          }  
  46.       }  
  47.    }  
  48.     
  49.    /** 
  50.     * 针对于URL进行封装的Resource,可用来从URL获取资源内容 
  51.     * @throws Exception 
  52.     */  
  53.    @Test  
  54.    public void testURL() throws Exception {  
  55.       UrlResource resource = new UrlResource("http://www.google.com.hk");  
  56.       if (resource.isReadable()) {  
  57.          //URLConnection对应的getInputStream()。  
  58.          printContent(resource.getInputStream());  
  59.       }  
  60.    }  
  61.     
  62.    /** 
  63.     * 针对于字节数组封装的Resource,用来从字节数组获取资源内容 
  64.     * @throws IOException 
  65.     */  
  66.    @Test  
  67.    public void testByteArray() throws IOException {  
  68.       ByteArrayResource resource = new ByteArrayResource("Hello".getBytes());  
  69.       //ByteArrayInputStream()  
  70.       printContent(resource.getInputStream());  
  71.    }  
  72.     
  73.    /** 
  74.     * 针对于输入流的Resource,其getInputStream()方法只能被调用一次。 
  75.     * @throws Exception 
  76.     */  
  77.    @Test  
  78.    public void testInputStream() throws Exception {  
  79.       InputStream is = new FileInputStream("D:\\test.txt");  
  80.       InputStreamResource resource = new InputStreamResource(is);  
  81.       //对于InputStreamResource而言,其getInputStream()方法只能调用一次,继续调用将抛出异常。  
  82.       InputStream target = resource.getInputStream();   //返回的就是构件时的那个InputStream  
  83.       //is将在printContent方法里面进行关闭  
  84.       printContent(target);  
  85.    }  
  86.     
  87.    /** 
  88.     * 输出输入流的内容 
  89.     * @param is 
  90.     * @throws IOException 
  91.     */  
  92.    private void printContent(InputStream is) throws IOException {  
  93.       BufferedReader br = new BufferedReader(new InputStreamReader(is));  
  94.       String line;  
  95.       while ((line=br.readLine()) != null) {  
  96.          System.out.println(line);  
  97.       }  
  98.       if (is != null) {  
  99.          is.close();  
  100.       }  
  101.       if (br != null) {  
  102.          br.close();  
  103.       }  
  104.    }  
  105.     
  106. }  

 

 

2       通过ResourceLoader获取资源

       在Spring里面还定义有一个ResourceLoader接口,该接口中只定义了一个用于获取Resource的getResource(String location)方法。它的实现类有很多,这里我们先挑一个DefaultResourceLoader来讲。DefaultResourceLoader在获取Resource时采用的是这样的策略:首先判断指定的location是否含有“classpath:”前缀,如果有则把location去掉“classpath:”前缀返回对应的ClassPathResource;否则就把它当做一个URL来处理,封装成一个UrlResource进行返回;如果当成URL处理也失败的话就把location对应的资源当成是一个ClassPathResource进行返回。

Java代码  收藏代码
  1. @Test  
  2. public void testResourceLoader() {  
  3.    ResourceLoader loader = new DefaultResourceLoader();  
  4.    Resource resource = loader.getResource("http://www.google.com.hk");  
  5.    System.out.println(resource instanceof UrlResource); //true  
  6.    //注意这里前缀不能使用“classpath*:”,这样不能真正访问到对应的资源,exists()返回false  
  7.    resource = loader.getResource("classpath:test.txt");  
  8.    System.out.println(resource instanceof ClassPathResource); //true  
  9.    resource = loader.getResource("test.txt");  
  10.    System.out.println(resource instanceof ClassPathResource); //true  
  11. }  

 

       ApplicationContext接口也继承了ResourceLoader接口,所以它的所有实现类都实现了ResourceLoader接口,都可以用来获取Resource。

       对于ClassPathXmlApplicationContext而言,它在获取Resource时继承的是它的父类DefaultResourceLoader的策略。

       FileSystemXmlApplicationContext也继承了DefaultResourceLoader,但是它重写了DefaultResourceLoader的getResourceByPath(String path)方法。所以它在获取资源文件时首先也是判断指定的location是否包含“classpath:”前缀,如果包含,则把location中“classpath:”前缀后的资源从类路径下获取出来,当做一个ClassPathResource;否则,继续尝试把location封装成一个URL,返回对应的UrlResource;如果还是失败,则把location指定位置的资源当做一个FileSystemResource进行返回。

 

3       在bean中获取Resource的方式

       通过上面内容的介绍,我们知道,在bean中获取Resource主要有以下几种方式:

       1.直接通过new各种类型的Resource来获取对应的Resource。

       2.在bean里面获取到对应的ApplicationContext,再通过ApplicationContext的getResource(String path)方法获取对应的Resource。

     3.直接创建DefaultResourceLoader的实例,再调用其getResource(String location)方法获取对应的Resource。

       4.通过依赖注入的方式把Resource注入到bean中。示例如下:

 

类ClassA:

Java代码  收藏代码
  1. public class ClassA {  
  2.    
  3.    //持有一个Resource属性  
  4.    private Resource resource;  
  5.     
  6.    public void printContent() {  
  7.       if (resource != null && resource.exists()) {  
  8.          if (resource.isReadable()) {  
  9.             InputStream is;  
  10.             try {  
  11.                 is = resource.getInputStream();  
  12.                 BufferedReader br = new BufferedReader(new InputStreamReader(is));  
  13.                 String line;  
  14.                 while ((line=br.readLine()) != null) {  
  15.                    System.out.println(line);  
  16.                 }  
  17.                 if (is != null) {  
  18.                    is.close();  
  19.                 }  
  20.                 if (br != null) {  
  21.                    br.close();  
  22.                 }  
  23.             } catch (IOException e) {  
  24.                 e.printStackTrace();  
  25.             }  
  26.          }  
  27.       }  
  28.    }  
  29.     
  30.    public void setResource(Resource resource) {  
  31.       this.resource = resource;  
  32.    }  
  33.     
  34. }  

 

applicationContext.xml文件:

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <beans xmlns="http://www.springframework.org/schema/beans"   
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"   
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  5.          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
  6.          http://www.springframework.org/schema/context   
  7.          http://www.springframework.org/schema/context/spring-context-3.0.xsd">   
  8.    
  9.    <bean id="classA" class="com.xxx.ClassA">  
  10.       <property name="resource">  
  11.          <value>classpath:applicationContext.xml</value>  
  12.       </property>  
  13.    </bean>  
  14.    
  15. </beans>  

 

       从上面可以看到我们有一个类ClassA,其持有一个Resource属性,在Spring bean配置文件中我们直接给ClassA注入了属性resource。其对应的测试代码如下:

Java代码  收藏代码
  1. @RunWith(SpringJUnit4ClassRunner.class)  
  2. @ContextConfiguration("classpath:applicationContext.xml")  
  3. public class Test1 {  
  4.    
  5.    @Autowired  
  6.    private ClassA classA;  
  7.     
  8.    @Test  
  9.    public void test() {  
  10.       classA.printContent();  
  11.    }  
  12.     
  13. }  

 

java 文件移动 常规四种方法 和利用FileCopyUtils.copy( , )方法 使用 java 进行文件拷贝 相信很多人都会用,,不过效率上是否最好呢? 最近看了看NIO决定试一试 java  NIO 到底有什么性能的提升. 第一种方法:古老的方式  public static long forJava(File f1,File f2) throws Exception{   long time=new Date().getTime();   int lengt 阅读详情

相关推荐

ComfyUI入门学习-教程篇

深入的 ComfyUI 教程,不同功能节点的详细指南。一个比较有意思的Comfyui教程,动画式学习。从安装到基础教程、高级教程再到各种工作流。非常全面,有教程有搭建好的工作流。

wincyfu的博客 1320

Spring中的FileCopyUtils:文件复制的利器与详解

在Spring框架中,FileCopyUtils是一个用于文件复制操作的实用工具类。它提供了一系列静态方法,简化了文件从输入流到输出流、从文件到文件等的复制过程。这些方法都基于NIO(New I/O)技术,提供了高效的文件复制能力。

m0_51176516的博客 2250

RobotStudio码垛机器人创建过程

首先导入一个IRB2600机器人,移动夹具的本地坐标原点,使原点位置为顶面中心(与法兰盘连接的部位)。对齐夹爪Smart组件的本地坐标和机器人末端法兰盘的坐标...

个人博客 1万+

Springboot内置的工具类之FileCopyUtils

Spring内置的工具类里,最喜欢用的就是文件读写这一部分,虽然原生的写法也没几句,但是就是懒,不想循环、判断什么的,直接调用现成的静态方法,多高效,哈哈,这就是懒人必备。

凡夫编程 3422

Lane、PHY和Preset Value Bit

每个Lane支持不同的传输速度和带宽,例如PCIe 3.0中,一个Lane的传输速度可以达到8 GT/s(Giga Transfers per second),也就是1 GB/s(GigaBytes per second)。Preset Value Bit(预置值位)是在PCIe 3.0的Lane上新引入的一种机制,用于优化信号传输质量。PCIe设备可以包含多个Lane,例如x1、x4、x8、x16等,表示该设备同时使用的Lane数目,比如x16表示该设备采用了16个Lane,具有更高的传输速度和带宽。

weixin_58083606的博客 1295

从5V降到3.3V,你的LDO到底有多烫?手把手算功耗、选散热,避开这些坑

本文详细解析了LDO在5V转3.3V电路中的发热问题,提供了精确的功耗计算公式和散热设计方法。通过对比不同封装的热阻参数和优化PCB布局,帮助工程师有效降低LDO温度,避免热保护触发。文章还探讨了替代方案的技术拐点,为电源系统优化设计提供实用指导。

weixin_30304375的博客 433

spring资源访问利器之FileCopyUtils

实现文件的拷贝 package com.smart.resource; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.core.io.support.EncodedResource; ...

zhuhaoyu6666的博客 5037

C#实践项目1

需求: 在CAD内实现两个坐标系的转换。 转换方式为文件内的所有图形从一个坐标系下的坐标,转换到另一个坐标系下的坐标。 进行坐标转换后,仅仅是坐标发生改变,图层、样式等等不会发生变化。

weixin_51182789的博客 5321

Spring Resource接口获取资源

1.1.1. Resource简介  在Spring内部实现机制,针对于资源文件(配置的xml文件)有一个统一的接口Resource。   1.1.1.1. 接口定义的方法 1.exists():判断资源文件是否存在。 2.isReadable():用于判断对应资源的内容是否可读。返回false肯定不可读,true也不一定可读。 3.isOpen():用于判断当前资源是否代表一个已打开

分享牛 3597

【文本分析学习】Anaconda+pytorch虚拟环境下的pycharm文本分析(含分词、词性标注、词形归一化、停用词、文本情感分析、词频、文本相似度,附数据代码) NLTK

文本分析学习之 Anadconda+pytorch虚拟环境下的pycharm文本分析(含分词、词性标注、词形归一化、停用词、文本情感分析、词频、文本相似度,附数据代码)

littlexmj的博客 2328

国产信创服务器软硬件兼容情况1 --- ARM架构

信创,即信息技术应用创新产业,它是数据安全、网络安全的基础,也是新基建的重要组成部分...

一只猿的自我修养 4736

Claude Code Auto Mode权限治理实战指南

AI编码助手的权限管理本质是平衡安全与效率的基础工程。其核心原理在于将传统人肉审批升级为基于路径、操作类型和上下文标签的策略化自动决策,通过可配置的规则引擎实现精准放行与拦截。这种机制不仅提升开发流体验,更支撑ISO 27001等合规审计要求,在金融、车载、SaaS等强监管场景中具备关键技术价值。实际落地需结合permissions.yaml策略文件、CLI版本控制、离线fallback机制及VS Code深度集成,尤其关注claude --permission-mode auto命令背后的策略加载逻辑与n

weixin_34320724的博客 326

模型训练篇 | 手把手教你使用ResNet训练自己数据集和推理,ResNet50通用物体分类识别,含完整代码和数据集,全网最详细教程

手把手教你使用ResNet训练自己数据集和推理,ResNet50通用物体分类识别,含完整代码和数据集,全网最详细教程。本篇文章将带你学习 ResNet50 模型构建、ResNet50训练自己数据集、数据集处理、推理和验证、模型剪枝与模型改进等。 本篇教程适配各种分类识别任务,可以说是一个通用的教程,只需修改自己的数据集即可完成自己领域的任务和系统实现。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 717
上一篇: 四种XML解析方式详解
下一篇: spring的ioc之Resource
有情有义z
博客等级 码龄13年 1粉丝 0原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值