Class,ClassLoader的getResource()和getResourceAsStream()区别

     今天研究Spring源码中Resource的时候,用到其工具类ResourceUtils其中的getFile(String resourceLocation)。发现了Class和ClassLoader的这两个方法。先把我的工程目录贴到这儿吧,如下图:

Java代码如下:

public   class  ResourceTest  {

    
public static String FILE_NAME = "ResourceTest_zh_CN.properties";
    
public static String ABSOLUTE_PATH = 
    
"E:/project/designpattern/classes/";
    
    
public static void main(String[] args) throws Exception {
    File file 
= ResourceUtils.getFile("classpath:" + FILE_NAME);
    print(file);
    file 
= ResourceUtils.getFile("file:" + ABSOLUTE_PATH + FILE_NAME);
    print(file);
    }

    
    
public static void print(File file) throws Exception {
    System.out.println(
"======================================================");
    System.out.println(
"class name = " + file.getClass().getName());
    System.out.println(
"file name = " + file.getName());
    System.out.println(
"file exists? = " + file.exists());
    System.out.println(
"file absolute path = " + file.getAbsolutePath());
    }

}

以上都是运行结果正确的,输出如下:

======================================================
class  name  =  java.io.File
file name 
=  ResourceTest_zh_CN.properties
file exists
?   =   true
file absolute path 
=  E:/project/designpattern/classes/ResourceTest_zh_CN.properties
======================================================
class  name  =  java.io.File
file name 
=  ResourceTest_zh_CN.properties
file exists
?   =   true
file absolute path 
=  E:/project/designpattern/classes/ResourceTest_zh_CN.properties

但是如果我把ResourceTest_zh_CN.properties剪切到resource目录下,无论怎么执行都报FileNotFoundException。看了一下ResourceUtils的源代码:

public   static  File getFile(String resourceLocation)  throws  FileNotFoundException  {
        Assert.notNull(resourceLocation, 
"Resource location must not be null");
        
if (resourceLocation.startsWith(CLASSPATH_URL_PREFIX)) {
            String path 
= resourceLocation.substring(CLASSPATH_URL_PREFIX.length());
            String description 
= "class path resource [" + path + "]";
            URL url 
= ClassUtils.getDefaultClassLoader().getResource(path);
            
if (url == null{
                
throw new FileNotFoundException(
                        description 
+ " cannot be resolved to absolute file path " +
                        
"because it does not reside in the file system");
            }

            
return getFile(url, description);
        }

        
try {
            
// try URL
            return getFile(new URL(resourceLocation));
        }

        
catch (MalformedURLException ex) {
            
// no URL -> treat as file path
            return new File(resourceLocation);
        }

}

从上可以看出ResourceUtils是通过ClassLoader的getResource方法来取得文件的。这儿岔开话题一下,可以注意到Class也有getResource和getResourceAsStream方法,这两个有什么区别呢?用代码来说话吧,先看一下目录图如下:

 代码如下:

public   class  ResourceTest  {

    
public static String FILE_NAME = "ResourceTest_zh_CN.properties";
    
public static String ABSOLUTE_PATH = 
    
"E:/project/designpattern/classes/";
    
    
public static void main(String[] args) throws Exception {

    System.out.println(ResourceTest.
class.getClassLoader().getResource("com/learn/spring/test/resource/" + FILE_NAME));
    System.out.println(ResourceTest.
class.getClassLoader().getResourceAsStream("com/learn/spring/test/resource/" + FILE_NAME));    
    System.out.println(ResourceTest.
class.getResource(FILE_NAME));
    System.out.println(ResourceTest.
class.getResourceAsStream(FILE_NAME));
    }

}

这样输出结果正确,显然ClassLoader和Class的两个方法的区别一看便知,它们相对路径不一样,Class是把class文件所在的目录做为根目录,ClassLoader是把加载所有classpath的目录为根目录,也就是“..../classes”。

好,回到Spring的代码,如果把ResourceTest_zh_CN.properties剪切到resource目录下,而且要第一段代码执行正确的话,我们可以这样修改(上面的Class和ClassLoader的两个方法的对比已经很清楚),更改代码如下就可以了:

public   class  ResourceTest  {

    
public static String FILE_NAME = "ResourceTest_zh_CN.properties";
    
public static String ABSOLUTE_PATH = 
    
"E:/project/designpattern/classes/";
    
    
public static void main(String[] args) throws Exception {
    
// TODO Auto-generated method stub
    Resource resource = null;
    
    resource 
= new ClassPathResource(FILE_NAME, ResourceTest.class);
    print(resource);
    resource 
= new FileSystemResource(ABSOLUTE_PATH + "com/learn/spring/test/resource/" + FILE_NAME);
    print(resource);
    File file 
= ResourceUtils.getFile("classpath:" +  "com/learn/spring/test/resource/" + FILE_NAME);
    print(file);
    file 
= ResourceUtils.getFile("file:" + ABSOLUTE_PATH + "com/learn/spring/test/resource/" + FILE_NAME);
    print(file);
    }

    
    
public static void print(Resource resource) throws Exception {
    System.out.println(
"======================================================");
    System.out.println(
"class name = " + resource.getClass().getName());
    System.out.println(
"file name = " + resource.getFilename());
    System.out.println(
"file exists? = " + resource.exists());
    System.out.println(
"file url = " + resource.getURL());
    System.out.println(
"file description = " + resource.getDescription());
    }

    
    
public static void print(File file) throws Exception {
    System.out.println(
"======================================================");
    System.out.println(
"class name = " + file.getClass().getName());
    System.out.println(
"file name = " + file.getName());
    System.out.println(
"file exists? = " + file.exists());
    System.out.println(
"file absolute path = " + file.getAbsolutePath());
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值