java文件路径问题及getResource和getClassLoader().getResource的区别

我们经常在java的io操作中读取文件,先看一个场景:


这样是读不到这个file文件的,会发生filenotfoundexception

如果我把文件放到了src/main/java下呢,还是会发生filenotfoundexception。

这里就涉及到一个java编译时的问题,请看图:


如果我的:

File f = new File("F:\\bi\\Generate\\src\\main\\java\\1.txt"); 试用未编译前的绝对路径,当然是可以读到文件内容的。

那么问题来了,我们经常在web项目中引用一个这样文件,但是上传的是打包后的经过编译的源码,这个绝对路径就不存在了,那么打包后的1.txt位于何处呢?在这里:


我们怎么才能读到这个文件呢,下面就引入了java提供的getClassLoader().getResource和getResource的问题,我们先看下面这段代码:

public class TestFile {
    
    @Test
    public void test1() throws IOException {
        System.out.println(TestFile.class.getResource("/")); //到classes目录
        System.out.println(TestFile.class.getResource("")); //到具体包所在目录
        System.out.println(TestFile.class.getClassLoader().getResource("")); //到classes目录
        System.out.println(TestFile.class.getClassLoader().getResource("/")); // null

//        File f = new File("F:\\bi\\Generate\\src\\main\\java\\1.txt");
//        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
//        String line = "";
//        while((line = br.readLine()) != null) {
//            System.out.println(line);
//        }
        
    }
}

结果为:

file:/F:/bi/Generate/target/test-classes/
file:/F:/bi/Generate/target/classes/com/tanlei/test/
file:/F:/bi/Generate/target/test-classes/
null

结论就是:

TestFile.class.getResource("/") 到编译后的classes目录,只不过加了前缀 file:

TestFile.class.getResource("")到具体包所在目录,只不过加了前缀 file:

TestFile.class.getClassLoader().getResource("") 到编译后的classes目录,只不过加了前缀 file:

TestFile.class.getClassLoader().getResource("/") 为null,获取不到

TestFile.class.getResource("/") = TestFile.class.getClassLoader().getResource("") 

这里还有个问题就是:

getResource和getResourceAsStream的区别,

getResourceAsStream是返回所在文件的流,下面这段代码的解释显而易见:


先看图,1.txt的位置如下


值得注意的是:

在maven中:

src/main/java和src/main/resource的内容在编译后都位于/target/classes/目录下;

src/test/java和src/test/resource的内容在编译后都位于/target/test-classes/目录下;

我们要获取位于/target/classes/下的1.txt,代码可以改变如下:

import org.junit.Test;

public class TestFile {
    
    @Test
    public void test1() throws IOException {
        System.out.println(TestFile.class.getResource("/")); //到classes目录
        System.out.println(TestFile.class.getResource("")); //到具体包所在目录
        System.out.println(TestFile.class.getClassLoader().getResource("")); //到classes目录
        System.out.println(TestFile.class.getClassLoader().getResource("/")); // null

//        File f = new File("F:\\bi\\Generate\\src\\main\\java\\1.txt");
//        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
        BufferedReader br = new BufferedReader(new InputStreamReader(TestFile.class.getResourceAsStream("/1.txt")));
        String line = "";
        while((line = br.readLine()) != null) {
            System.out.println(line);
        }
        
    }
}
利用getResourceAsStream和前面所讲的四种情况的区别,即可获取文件的流。

是不是已经讲的很清楚了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值