zoukankan      html  css  js  c++  java
  • Spring 中——————ClassPathResource初学

    感谢作者分享:本文内容来源:https://blog.csdn.net/YangLiehui/article/details/98599253

    org.springframewoek.core.io.classPathReource位于Spring核心core下,用于表达类路径下的资源

    首先简单说明一下什么是classPath,顾名思义,就是存放*。class类文件路径,或者说ClassLoader加载类时为了找到*.class文件的路径。我们以一个web项目为例,发布后的目录结构大致如下:

     对于部署在tomcat的WEB应用来说,/web-inf/classes 和web/inf/lib目录就是我们的classspath。

    ClassPathResource是org.springframewoek.core.io.Resource接口的实现类可以使用ClassLoader 加载资源,支持转换为java.io.file对象(在jar文件中的资源除外)他的类继承关系图如下:

     ClassPathResource类属性变量和类构造方法如下:

    private final String path;
        @Nullable
        private ClassLoader classLoader;// 通过ClassLoader加载资源文件
        @Nullable
        private Class<?> clazz; // 通过Class类加载资源文件
        
        // 通过类路径创建resource
        public ClassPathResource(String path){...}
        
        // 通过类路径和给定的ClassLoader创建resource
        public ClassPathResource(String path, @Nullable ClassLoader classLoader){...}
        
        // 通过类路径和给定的Class类创建resource
        public ClassPathResource(String path, @Nullable Class<?> clazz){...}
        
        // 通过类路径和给定的ClassLoader或Class创建resource
        protected ClassPathResource(String path, @Nullable ClassLoader classLoader, @Nullable Class<?> clazz){...}

    ClassPathResource的使用

    Resource resource = new ClassPathResource("conf/custom-beans.xml");

    System.out.println(resource.getURL());
    System.out.println(resource.getFilename());
    System.out.println(resource.getFile().getPath());
    public static String readSpringResourceToString(String fileName) {
            String content = "";
            ClassPathResource cpr = new ClassPathResource("/" + fileName);
            try {
                byte[] bdata = FileCopyUtils.copyToByteArray(cpr.getInputStream());
                content = new String(bdata, StandardCharsets.UTF_8);
            } catch (FileNotFoundException efn) {
                logger.warn("File not found. {}", fileName);
            } catch (IOException e) {
                logger.error("Error reading file {}", fileName);
            }
            return content;
        }

    //读取classpathresource文件中xml的方法。

    感谢作者:下面内容转载自:https://blog.csdn.net/qq_34337272/article/details/80349017

    文件IO的基石:Path

    java7中文件IO发生了很大的变化,专门引入了很多新的类来取代原来的基于java.io.File文件IO操作方式

    import java.nio.file.DirectoryStream;
    import java.nio.file.FileSystem;
    import java.nio.file.FileSystems;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.nio.file.attribute.FileAttribute;
    import java.nio.file.attribute.PosixFilePermission;
    import java.nio.file.attribute.PosixFilePermissions;·
    
    ......等等
    ————————————————

    我们将从下面几个方面来学习Path类: 
    - 创建一个Path 
    - File和Path之间的转换,File和URI之间的转换 
    - 获取Path的相关信息 
    - 移除Path中的冗余项

    1.创建一个Path

    创建Path实例可以通过Paths工具类的get()方法:

    //使用绝对路径
    Path path= Paths.get("c:\data\myfile.txt");
    //使用相对路径
    Path path = Paths.get("/home/jakobjenkov/myfile.txt");
    //下面的创建路径和上面的创建路径是等效的。
    Path path = FileSystems.getDefault().getPath("c:\data\myfile.txt");
    //获取当前的相对路径
      Path currentRelativePath = Paths.get("");
    //转化为绝对路径
    currentRelativeDir = currentRelativePath.toAbsolutePath().toString();
    //Path读取文件
    public
    static String readFileToString(String fileName) { String content = null; InputStream in = null; try { in = new FileInputStream(currentRelativeDir + fileName); content = IOUtils.toString(in, StandardCharsets.UTF_8); in.close(); // close errors are handled } catch (Exception e) { logger.warn("Error reading file {}, try to read it from jar", currentRelativeDir + fileName, e); content = readSpringResourceToString(fileName); } finally { IOUtils.closeQuietly(in); }
    //classPathResource  读取文件
    public static String readSpringResourceToString(String fileName) {
            String content = "";
            ClassPathResource cpr = new ClassPathResource("/" + fileName);
            try {
                byte[] bdata = FileCopyUtils.copyToByteArray(cpr.getInputStream());
                content = new String(bdata, StandardCharsets.UTF_8);
            } catch (FileNotFoundException efn) {
                logger.warn("File not found. {}", fileName);
            } catch (IOException e) {
                logger.error("Error reading file {}", fileName);
            }
            return content;
        }

    2. File 和path之间的相互转换

            File file = new File("C:/my.ini");
            Path p1 = file.toPath();
            p1.toFile();
            file.toURI();    

    3.获取Path相关信息

     //使用Paths工具类的get()方法创建
            Path path = Paths.get("D:\XMind\bcl-java.txt");
    /*        //使用FileSystems工具类创建
            Path path2 = FileSystems.getDefault().getPath("c:\data\myfile.txt");*/
            System.out.println("文件名:" + path.getFileName());
            System.out.println("名称元素的数量:" + path.getNameCount());
            System.out.println("父路径:" + path.getParent());
            System.out.println("根路径:" + path.getRoot());
            System.out.println("是否是绝对路径:" + path.isAbsolute());
            //startsWith()方法的参数既可以是字符串也可以是Path对象
            System.out.println("是否是以为给定的路径D:开始:" + path.startsWith("D:\") );

    4. 一处冗余项目

    某些时候在我们需要处理Path路径中可能会有一个或两个点

    -.表示当前目录

    -..表示父母了或者上衣级目录

    下面通过实例来完成使用Path中的normalize()和toRealPath()把.和..移除

    //.表示的是当前目录
            Path currentDir = Paths.get(".");
            System.out.println(currentDir.toAbsolutePath());//输出C:UsersAdministratorNIODemo.
            Path currentDir2 = Paths.get(".\NIODemo.iml");
            System.out.println("原始路径格式:"+currentDir2.toAbsolutePath());
            System.out.println("执行normalize()方法之后:"+currentDir2.toAbsolutePath().normalize());
            System.out.println("执行toRealPath()方法之后:"+currentDir2.toRealPath());
    
            //..表示父目录或者说是上一级目录:
            Path currentDir3 = Paths.get("..");
            System.out.println("原始路径格式:"+currentDir3.toAbsolutePath());
            System.out.println("执行normalize()方法之后:"+currentDir3.toAbsolutePath().normalize());
            System.out.println("执行toRealPath()方法之后:"+currentDir3.toRealPath());
    C:UsersAdministratorNIODemo.
    原始路径格式:C:UsersAdministratorNIODemo.NIODemo.iml
    执行normalize()方法之后:C:UsersAdministratorNIODemoNIODemo.iml
    执行toRealPath()方法之后:C:UsersAdministratorNIODemoNIODemo.iml
    原始路径格式:C:UsersAdministratorNIODemo..
    执行normalize()方法之后:C:UsersAdministrator
    执行toRealPath()方法之后:C:UsersAdministrator
    ————————————————

    二:拥抱Files

    Files是一个工具类,内部提供了很多方法。

     创建文件/文件夹
    Path target2 = Paths.get("C:\mystuff.txt");
            try {
                if(!Files.exists(target2))
                    Files.createFile(target2);
            } catch (IOException e) {
                e.printStackTrace();
            }
    创建文件夹:
     Path path = Paths.get("D://data//test");
    
        try {
            Path newDir = Files.createDirectories(path);
        } catch(FileAlreadyExistsException e){
            // the directory already exists.
        } catch (IOException e) {
            //something else went wrong
            e.printStackTrace();
        }
    删除文件或目录
    Path path = Paths.get("data/subdir/logging-moved.properties");
    
    try {
        Files.delete(path);
    } catch (IOException e) {
        //deleting file failed
        e.printStackTrace();
    }
    把一个文件从一个地址复制到另一个位置
    Path sourcePath      = Paths.get("data/logging.properties");
    Path destinationPath = Paths.get("data/logging-copy.properties");
    
    try {
        Files.copy(sourcePath, destinationPath);
    } catch(FileAlreadyExistsException e) {
        //destination file already exists
    } catch (IOException e) {
        //something else went wrong
        e.printStackTrace();
    }
    获取文件属性
    Path path = Paths.get("D:\XMind\bcl-java.txt");
            System.out.println(Files.getLastModifiedTime(path));
            System.out.println(Files.size(path));
            System.out.println(Files.isSymbolicLink(path));
            System.out.println(Files.isDirectory(path));
            System.out.println(Files.readAttributes(path, "*"));
    
    遍历一个文件夹
     Path dir = Paths.get("D:\Java");
            try(DirectoryStream<Path> stream = Files.newDirectoryStream(dir)){
                for(Path e : stream){
                    System.out.println(e.getFileName());
                }
            }catch(IOException e){
    
            }
    遍历整个文件目录:
    
    public class WorkFileTree {
    
        public static void main(String[] args) throws IOException{
            Path startingDir = Paths.get("D:\apache-tomcat-9.0.0.M17");
            List<Path> result = new LinkedList<Path>();
            Files.walkFileTree(startingDir, new FindJavaVisitor(result));
            System.out.println("result.size()=" + result.size());
        }
    
        private static class FindJavaVisitor extends SimpleFileVisitor<Path>{
            private List<Path> result;
            public FindJavaVisitor(List<Path> result){
                this.result = result;
            }
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs){
                if(file.toString().endsWith(".java")){
                    result.add(file.getFileName());
                }
                return FileVisitResult.CONTINUE;
            }
        }
    }

    遍历整个目录:该代码涉及的很巧妙,研究该涉及模式

    1 检查给定的Path在文件系统中是否存在通过 Files.exists() 检测文件路径是否存在:
           Path path = Paths.get("D:\XMind\bcl-java.txt");
            boolean pathExists =                Files.exists(path,                        new LinkOption[]{LinkOption.NOFOLLOW_LINKS});        System.out.println(pathExists);//true123456注意Files.exists()的的第二个参数。它是一个数组,这个参数直接影响到Files.exists()如何确定一个路径是否存在。在本例中,这个数组内包含了LinkOptions.NOFOLLOW_LINKS,表示检测时不包含符号链接文件。
    2 创建文件/文件夹创建文件:通过 Files.createFile() 创建文件,
            Path target2 = Paths.get("C:\mystuff.txt");        try {            if(!Files.exists(target2))                Files.createFile(target2);        } catch (IOException e) {            e.printStackTrace();        }1234567创建文件夹:
    通过 Files.createDirectory() 创建文件夹通过 Files.createDirectories() 创建文件夹Files.createDirectories()会首先创建所有不存在的父目录来创建目录,而Files.createDirectory()方法只是创建目录,如果它的上级目录不存在就会报错。比如下面的程序使用Files.createDirectory() 方法创建就会报错,这是因为我的D盘下没有data文件夹,加入存在data文件夹的话则没问题。
        Path path = Paths.get("D://data//test");
        try {        Path newDir = Files.createDirectories(path);    } catch(FileAlreadyExistsException e){        // the directory already exists.    } catch (IOException e) {        //something else went wrong        e.printStackTrace();    }123456789103 删除文件或目录通过 Files.delete()方法 可以删除一个文件或目录:
    Path path = Paths.get("data/subdir/logging-moved.properties");
    try {    Files.delete(path);} catch (IOException e) {    //deleting file failed    e.printStackTrace();}123456784 把一个文件从一个地址复制到另一个位置通过Files.copy()方法可以吧一个文件从一个地址复制到另一个位置
    Path sourcePath      = Paths.get("data/logging.properties");Path destinationPath = Paths.get("data/logging-copy.properties");
    try {    Files.copy(sourcePath, destinationPath);} catch(FileAlreadyExistsException e) {    //destination file already exists} catch (IOException e) {    //something else went wrong    e.printStackTrace();}1234567891011copy操作还可可以强制覆盖已经存在的目标文件,只需要将上面的copy()方法改为如下格式:
        Files.copy(sourcePath, destinationPath,            StandardCopyOption.REPLACE_EXISTING);125 获取文件属性        Path path = Paths.get("D:\XMind\bcl-java.txt");        System.out.println(Files.getLastModifiedTime(path));        System.out.println(Files.size(path));        System.out.println(Files.isSymbolicLink(path));        System.out.println(Files.isDirectory(path));        System.out.println(Files.readAttributes(path, "*"));123456结果:
    2016-05-18T08:01:44Z18934falsefalse{lastAccessTime=2017-04-12T01:42:21.149351Z, lastModifiedTime=2016-05-18T08:01:44Z, size=18934, creationTime=2017-04-12T01:42:21.149351Z, isSymbolicLink=false, isRegularFile=true, fil123456 遍历一个文件夹        Path dir = Paths.get("D:\Java");        try(DirectoryStream<Path> stream = Files.newDirectoryStream(dir)){            for(Path e : stream){                System.out.println(e.getFileName());            }        }catch(IOException e){
            }12345678结果:
    apache-maven-3.5.0Eclipseintellij ideaJarJDKMarvenRespositoryMyEclipse 2017 CINodejsRedisDesktopManagersolr-7.2.112345678910上面是遍历单个目录,它不会遍历整个目录。遍历整个目录需要使用:Files.walkFileTree().Files.walkFileTree()方法具有递归遍历目录的功能。
    7 遍历整个文件目录:walkFileTree接受一个Path和FileVisitor作为参数。Path对象是需要遍历的目录,FileVistor则会在每次遍历中被调用。
    FileVisitor需要调用方自行实现,然后作为参数传入walkFileTree().FileVisitor的每个方法会在遍历过程中被调用多次。如果不需要处理每个方法,那么可以继承它的默认实现类SimpleFileVisitor,它将所有的接口做了空实现。
    public class WorkFileTree {
        public static void main(String[] args) throws IOException{        Path startingDir = Paths.get("D:\apache-tomcat-9.0.0.M17");        List<Path> result = new LinkedList<Path>();        Files.walkFileTree(startingDir, new FindJavaVisitor(result));        System.out.println("result.size()=" + result.size());    }
        private static class FindJavaVisitor extends SimpleFileVisitor<Path>{        private List<Path> result;        public FindJavaVisitor(List<Path> result){            this.result = result;        }        @Override        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs){            if(file.toString().endsWith(".java")){                result.add(file.getFileName());            }            return FileVisitResult.CONTINUE;        }    }}1234567891011121314151617181920212223上面这个例子输出了我的D:apache-tomcat-9.0.0.M17也就是我的Tomcat安装目录下以.java结尾文件的数量。
    结果:————————————————版权声明:本文为CSDN博主「Guide哥」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qq_34337272/java/article/details/80349017

  • 相关阅读:
    C#中的编译为什么不叫Compile而叫build
    类型(Type)
    C#中关于值类型和引用类型的区别
    php通用化api格式输出
    tp6获取参数的五种办法
    PHP 数组------分割、合并
    explain结果中的type字段的含义
    order by 排序
    SQL开发技巧
    tp5模板输出日期时间
  • 原文地址:https://www.cnblogs.com/dousil/p/12875794.html
Copyright © 2011-2022 走看看