码迷,mamicode.com
首页 > 编程语言 > 详细

java踩坑记-getResourceAsStream

时间:2017-12-17 18:19:13      阅读:540      评论:0      收藏:0      [点我收藏+]

标签:col   indexof   blog   ref   color   分享   没有   put   绝对路径   

本文主要是研究下面集中方法到底谁才能真正的load到文件,你能一眼看出来吗?

GetResourcesSample.class.getClassLoader.getResourceAsStream("main-resources-file.txt") 
GetResourcesSample.class.getClass().getResourceAsStream("main-resources-file.txt") 
GetResourcesSample.class.getResourceAsStream("main-resources-file.txt") 
 
GetResourcesSample.class.getClassLoader.getResourceAsStream("/main-resources-file.txt") 
GetResourcesSample.class.getClass().getResourceAsStream("/main-resources-file.txt") 
GetResourcesSample.class.getResourceAsStream("/main-resources-file.txt") 
 
很晕吧,反正我是挺晕的。
 

目录结构:

技术分享图片

 

代码:

public class GetResourcesSample {
    private static final String MAIN_FILE = "main-resources-file.txt";
    private static final String MAIN_FILE_WITH_SLASH = "/main-resources-file.txt";
    private static final String TEST_FILE = "test-resources-file.txt";
    private static final String TEST_FILE_WITH_SLASH = "/test-resources-file.txt";
    private static final String ROOT_FILE = "project-root-file.txt";
    private static final String ROOT_FILE_WITH_SLASH = "./project-root-file.txt";

    public static void main(String[] args) {
        validateResult(MAIN_FILE);
        validateResult(MAIN_FILE_WITH_SLASH);

        validateResult(TEST_FILE);
        validateResult(TEST_FILE_WITH_SLASH);

        validateResult(ROOT_FILE);
        validateResult(ROOT_FILE_WITH_SLASH);

    }

    private static void validateResult(String file) {

        InputStream inputStream1 = GetResourcesSample.class.getClass().getResourceAsStream(file);
        if (inputStream1 != null) {
            System.out.println(MessageFormat
                    .format("GetResourcesSample.class.getClass().getResourceAsStream(\"{0}\") is not null!", file));
        }

        InputStream inputStream2 = GetResourcesSample.class.getResourceAsStream(file);
        if (inputStream2 != null) {
            System.out.println(
                    MessageFormat.format("GetResourcesSample.class.getResourceAsStream(\"{0}\") is not null!", file));
        }

        InputStream inputStream3 = GetResourcesSample.class.getClassLoader().getResourceAsStream(file);
        if (inputStream3 != null) {
            System.out.println(
                    MessageFormat.format("GetResourcesSample.class.getClassLoader().getResourceAsStream(\"{0}\") is not null!", file));
        }

    }
}

结果:

GetResourcesSample.class.getClassLoader().getResourceAsStream("main-resources-file.txt") is not null!
GetResourcesSample.class.getClass().getResourceAsStream("/main-resources-file.txt") is not null!
GetResourcesSample.class.getResourceAsStream("/main-resources-file.txt") is not null!

 

结论:

  1. Class.getResourceAsStream 最终调用的是此Class的Class Loader的getResourceAsStream来进行读文件(有些绕,尽量理解)
  2. GetResourcesSample.class.getClass() 得到的是Class这个类的实例,它的ClassLoader是JVM的bootstrap Class Loader
  3. GetResourcesSample.class.getResourceAsStream 由于去resolve了一下name,虽然是当前class的ClassLoader,它也读不到这个文件;除非你的文件名以“/”开头。详见源代码:
        /**
         * Add a package name prefix if the name is not absolute Remove leading "/"
         * if name is absolute
         */
        private String resolveName(String name) {
            if (name == null) {
                return name;
            }
            if (!name.startsWith("/")) {
                Class<?> c = this;
                while (c.isArray()) {
                    c = c.getComponentType();
                }
                String baseName = c.getName();
                int index = baseName.lastIndexOf(‘.‘);
                if (index != -1) {
                    name = baseName.substring(0, index).replace(‘.‘, ‘/‘)
                        +"/"+name;
                }
            } else {
                name = name.substring(1);
            }
            return name;
        }
  4. project-root-file.txt这种最后最终不被打在Jar包里的文件,是没有机会被读取的,除非hard code一个文件所在的绝对路径
  5. 把相同代码放到UT里面去跑,会发现UT能同时load到main和test下的文件。因为JUnit有它自己的ClassLoader,它能同时读到main和test下的文件。

java踩坑记-getResourceAsStream

标签:col   indexof   blog   ref   color   分享   没有   put   绝对路径   

原文地址:http://www.cnblogs.com/ydjfish/p/8052575.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!