美文网首页
资源访问

资源访问

作者: Scalelength | 来源:发表于2019-04-03 14:45 被阅读0次

预讲知识点

1.掌握Resource接口的使用

2.ResourceLoader接口使用

3.掌握各种资源数据的读取操作

具体内容

如果想要进行磁盘文件的读取操作,首先想到的一定是java.io包中提供的一系列类,还可以继续深入的想到:InputStream、OutputStream、Scanner、BufferedReader、PrintStream等核心的处理操作类。

但是现在有如下几个问题:

1.这几个类的相互操作难度太高,很多人实际上对于IO的领悟并不是很彻底;

2.IO支持的读取有限且复杂:

|-读取jar包里的文件;

|-读取不同资源文件的时候操作不统一,例如:读取文件、网络读取;

所以在整个Spring设计过程之中充分的考虑了IO操作的种种操作问题,那么提供了一套新的资源访问处理的操作支持,而整个操作的关键在于:org.springframework.core.io.Resource,而这个接口就表示所有的可用资源读取,在此接口里定义有如下的几个常用方法:

long contentLength() 取得资源的数据长度

boolean exists() 判断资源是否存在

File getFile() 取得资源对应的文件类信息

URL getURL() 取得资源的完整网络路径

boolean isOpen() 判断资源是否打开

long lastModified() 最后一次修改日期

Resource createRelative(String relativePath) 创建一个操作资源

Resource本身只属于一个子接口,它有一个对应的父接口:org.springframework.core.io.InputStreamSource在这个接口里面也定义有一些资源的操作方法:

InputStream getInputStream() 取得资源的输入流

Resource本身是一个接口,那么如果要想使用这个操作接口,需要找到它的子类:ByteArrayResource(内存读取)、ClassPathResource(CLASSPATH读取)、FileSystemResource(文件读取)、

4.1、读取不同资源

下面首先按照传统开发实现一些基本资源读取。

1、读取内存资源:org.springframework.core.io.ByteArrayResource

·构造方法:ByteArrayResource(byte[] byteArray);

范例:实现内存读取

import org.springframework.core.io.ByteArrayResource;

import org.springframework.core.io.Resource;

import java.util.Scanner;

public static void main(String[] args) throws Exception{

        //此处的内存处理流于之前讲解的ByteArrayInputStream使用形式类似

        Resource resource = new ByteArrayResource("helloworld".getBytes());

        //单单就可以取得更多的资源信息来讲,这一点比InputStream要强

        System.out.println("数据长度" + resource.contentLength());

        //如果给出的InputStream,那么可以利用Scanner简化

        //getInputStream是通过InputStreamSource父接口继承而来的方法

        Scanner scanner = new Scanner(resource.getInputStream());

        if(scanner.hasNext()){

            System.out.println(scanner.next());

        }

    }

    2、文件读取:org.springframework.core.io.FileSystemResource

    ·构造方法FileSystemResource(java.io.File file)

    FileSystemResource(java.lang.String path)

    范例:读取文件

    import org.springframework.core.io.FileSystemResource;

import org.springframework.core.io.Resource;

import java.io.File;

import java.util.Scanner;

    public static void main(String[] args) throws Exception{

        Resource resource = new FileSystemResource(new File("/Users/macpro/IdeaProjects/Spring/src/applicationContext.xml"));

        System.out.println("数据长度" + resource.contentLength());

        Scanner scanner = new Scanner(resource.getInputStream());

        scanner.useDelimiter("\n");

        if(scanner.hasNext()){

            System.out.println(scanner.next());

        }

    }

    如果要进行文件的读取,必须要提供有完整的路径,也就是说默认情况下要想读取一个置顶的资源,那么必须要拼凑出路径(需要取得一堆系统属性)

    3.CLASSPATH读取:org.springframework.core.io.ClassPathResource

    只要是保存在CLASSPATH环境属性下的路径信息都可以通过此类读取进来

    Resource resource = new ClassPathResource("applicationContext.xml");

        System.out.println("数据的长度"+resource.contentLength());

        Scanner scanner = new Scanner(resource.getInputStream());

        while (scanner.hasNext()){

            System.out.println(scanner.next());

        }

    4.3、ResourceLoader接口

    ResourceLoader接口的主要作用是进行org.springframework.core.io.ResourceLoader接口对象实例化使用的,这个接口的定义如下:

    ·读取指定的资源信息:Resource getResource(java.lang.String location)

    ·取得类加载器:java.lang.ClassLoader getClassLoader()

    ResourceLoader是一个接口,于是要使用这个接口必须知道他对应的子类:org.springframework.core.io.DefaultResourceLoader,利用这个子类就可以实现ResourceLoader接口实例化,但是现在资源操作的问题并不在于Resource或者是ResourceLoader接口以及其一堆的子类,而关键性的问题在于这个定位的字符串。

    ·文件读取资源:“file:路径”;

    ·CLASSPATH读取:“classpath:路径”;

    ·网络读取:”http://路径“。

    范例:

    import org.springframework.core.io.DefaultResourceLoader;

import org.springframework.core.io.Resource;

import org.springframework.core.io.ResourceLoader;

    public static void main(String[] args) throws Exception{

        ResourceLoader resourceLoader = new DefaultResourceLoader();

        Resource resource = resourceLoader.getResource("classpath:applicationContext.xml");

        System.out.println("文件长度"+resource.contentLength());

        Scanner scanner = new Scanner(resource.getInputStream());

        while(scanner.hasNext()){

            System.out.println(scanner.next());

        }

    }

    读取其他数据只修改getResource()中的内容就好了,格式按照范例之上的格式

    “file:/Users/macpro/IdeaProjects/Spring/src/applicationContext.xml”

    "http://bilibili.com"

    只是写了一个字符串,而后就可以进行读取了,可以清楚的感受到,都是利用了字符串来进行的资源定位,也就是说在整个Spring里面核心的设计思想就是:利用合理的字符串格式来进行

    4.3、注入Resource

    在以上的操作可以发现,虽然Resource的子类可以利用了字符串格式进行了隐藏,但是此时的代码之中ResourceLoader跟开发没有任何的关系。如果真的开发之关系Resource一个接口就够了。

    为了解决Resource于ResourceLoader关系的耦合问题,那么在Spring设计的时候考虑到数据的自动转型问题,也就是说注入的操作模式,就可以让ResourceLoaded消失。

    范例:编写一个资源处理类

import org.springframework.core.io.Resource;

public class ResourceBean {

    private Resource resource;

    public Resource getResource() {

        return resource;

    }

    public void setResource(Resource resource) {

        this.resource = resource;

    }

}

public static void main(String[] args) throws Exception{

        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        ResourceBean  resourceBean = ctx.getBean("rb",ResourceBean.class);

        Scanner scanner = new Scanner(resourceBean.getResource().getInputStream());

        scanner.useDelimiter("/n");

        while(scanner.hasNext()){

            System.out.println(scanner.next());

        }

    }

要想实资源数据的注入操作,就必须要编写applicationContext.xml文件,在这个文件里面定义所需要的资源。

范例:在applicationContext.xml文件中定义

<bean id="rb" class="cn.edu.util.ResourceBean">

        <property name="resource" value="file:/Users/macpro/IdeaProjects/Spring/src/applicationContext.xml"/>

    </bean>

    或者

    <property name="resource" value="classpath:applicationContext.xml"/>

    或者

    <property name="resource" value="http://bilibili.com"/>

    范例:测试代码

    public static void main(String[] args) throws Exception{

        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        ResourceBean  resourceBean = ctx.getBean("rb",ResourceBean.class);

        Scanner scanner = new Scanner(resourceBean.getResource().getInputStream());

        scanner.useDelimiter("/n");

        while(scanner.hasNext()){

            System.out.println(scanner.next());

        }

    }

    利用了配置文件的方式进行处理的时候,那么用户关心的只是Resource一个接口的作用被Spring封装起来了。

    而且最为方便的是,在Spring里面允许用户设置资源数组。

    范例:修改程序类

    public static void main(String[] args) throws Exception{

        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        ResourceList resourceList = ctx.getBean("rbList",ResourceList.class);

        Iterator<Resource> iterator = resourceList.getResource().iterator();

      while(iterator.hasNext()){

            Scanner scanner = new Scanner(iterator.next().getInputStream());

            while(scanner.hasNext()){

                System.out.println(scanner.next());

            }

            System.out.println("*************************************");

        }

    <bean id="rbList" class="cn.edu.util.ResourceList">

        <property name="resource">

            <list>

                <value>file:/Users/macpro/IdeaProjects/Spring/src/applicationContext.xml</value>

                <value>classpath:applicationContext.xml</value>

                <value>http://bilibili.com</value>

            </list>

        </property>

    </bean>

    private List<Resource> resource;

    public List<Resource> getResource() {

        return resource;

    }

    public void setResource(List<Resource> resource) {

      this.resource = resource;

  }

    利用Spring读取外部文件资源的时候它的设计要比直接使用IO包操作更加容易。

    4.4、路径通配符(重点)

    以上讲解的操作都以个共同的问题,那么就是必须设置好完整的路径,但是很多时候无法一一设置完整路径。例如,在不同目录下都会存在有“applicationContext-xxx.xml“命名结构,如果要想将其完整的读取进来,那么就必须考虑到路径的通配符使用,在Spring中继续发扬了ANT工具的特征,而在这个工具下提供有几种符号:

    ·“?”:匹配任意的一位字符

    ·“*”:匹配零个或多个任意的字符。

    ·“**”:表示匹配任意目录,可以是零个、一个或多个。

    但是一旦要进行多个路径的匹配那么返回的内容也一定是多个,此时只能利用resourceLoader进行读取:org.springframework.core.io.support.ResourcePatternResolver。可以使用子类:PathMatchingResourcePatternResolver。

    范例:读取资源

    public class ClassPathMany{

    public static void main(String[] args) throws Exception{

    ResourcePatternResolver loader = new PathMatchingResourcePatternResolver();

    Resource[] source = loader.getResource("classpath:cn/edu/**/applicationContext-?"));

    for(int x = 0; x < source.length; x++){

    System.out.println("文件名称:" + source[x].getFilename() + "数据长度" + source[x].contentLength());

    }

    }

    }

    在Spring里面目录的访问不再成为限制。

相关文章

  • 资源访问

    预讲知识点 1.掌握Resource接口的使用 2.ResourceLoader接口使用 3.掌握各种资源数据的读...

  • JavaWeb--Filter1

    放行后访问对应资源,资源访问完成后会回到Filter中Filter执行流程:执行放行前逻辑->放行->访问资源->...

  • day41HTTP网络协议说明

    课程介绍部分 作业: 网站访问资源概念 静态资源: 动态资源 伪静态资源 网站访问度量方式 企业常用网站web服务...

  • Rails 中使用 Arel 实现外连接查询

    例如有以下几个表 需求: 用户可以访问自己创建的资源 用户可以访问所属分组的资源 用户可以访问单独授权的资源 用 ...

  • springmvc、springboot静态资源访问配置

    如何访问项目中的静态资源? 一.springmvc springmvc中访问静态资源,如果DispatcherSe...

  • Spring资源访问

    文章内容来自本人学习《精通Spring 4.x 企业应用开发实战》一书的笔记整理,部分内容摘抄原文。 1、资源抽象...

  • 三、资源访问

    Spring框架大量使用了Resource来访问底层资源。Resource接口提供的方法: getInputStr...

  • 六、资源访问

    2019-05-31 资源 无法直接访问的原生资源,保存在assets目录下 可通过R资源清单类访问的资源,保存在...

  • Android资源访问

    Android资源访问 一、资源访问:【掌握】(一)、概念:Android中的资源是指可以在代码中使用的外部文件,...

  • java 并发编程相关知识点(一)

    共享资源 什么是共享资源?共享资源指的是多个线程同时对同一份资源进行访问(读写操作),被多个线程访问的资源...

网友评论

      本文标题:资源访问

      本文链接:https://www.haomeiwen.com/subject/orvabqtx.html