• 编译正常运行,打jar包运行报错(找不到文件路径)


    前言

    博主个人社区:开发与算法学习社区

    博主个人主页:Killing Vibe的博客

    欢迎大家加入,一起交流学习~~

    问题描述

    Maven项目下,从resouces目录下把文件读入内存时,例如将sql文件用文件输入流读入时,编译时运行正常,但打成jar包后运行jar包报错:

    Exception in thread “main” java.lang.RuntimeException:

    java.io.FileNotFoundException

    在这里插入图片描述


    原因分析:

    先上初始代码:

     InputStream in = new FileInputStream("src/main/resources/init.sql");
    
    • 1

    我们在获取文件输入流的时候大部分都会选择使用相对路径来读入一个文件(一般不使用绝对路径,可移植性太差)

    这个时候,正常去在项目下编译运行时没有任何问题的,但我们把这个项目打包成可执行jar包的时候,在终端运行这个jar包,就会报错,系统找不到指定的这个文件路径:

    在这里插入图片描述

    原因就在于此时打包后的jar包默认是在target文件夹下,而我们的代码默认的工作目录项目的目录,所以一旦在jar包所在目录运行这个jar包,相对路径就不对了,就会报路径错误。

    解决方案:

    1.把这个jar包移动到工作目录上运行(很笨的方法)

    2.下面推荐一种做法就是使用类加载器的方式引入资源文件

    先上代码:

     InputStream in = DBUtil.class.getClassLoader().
                        getResourceAsStream("init.sql");
    
    • 1
    • 2

    直接获取已有类的一个class对象的类加载器,然后用里面的 getResourceAsStream()方法 。

    注:已有类就是项目文件夹下的任何一个类,比如我在src/main/java下写了一个叫做DBUtil的类

    因为项目中的源文件打包编译之后都会放在 target 文件夹下的 classes 文件夹中(包括资源文件),而刚好这个jar包也是默认放在target文件夹下,所以两者工作目录相同,就不会报错

    简单解释一下这个方法的原理:

    • 调用DBUtil.class.getClassLoader()就会获取到编译后的classes目录
    • 所谓的类加载器就是告诉JVM从哪个文件夹去执行class文件
    • getResourceAsStream()就是获取指定文件的输入流

    总结

    好处:这就是处理相对路径的通用写法!!

    充分体现了Java的可移植性,无论哪个操作系统,哪个电脑,这样写一写百通~~~

    如果对各位有什么帮助的话,欢迎关注+点赞收藏,获取更多干货~

  • 相关阅读:
    搭建Spark所遇过的坑
    Solon2 之基础:一、常用应用配置说明
    RabbitMQ:消息队列的卓越之选
    安装Anaconda
    自动驾驶,是“平视”还是“俯视”?
    g 对象:Flask 应用中的“临时口袋”
    第〇篇:深入Docker的世界系列博客介绍
    Python&C++相互混合调用编程全面实战-20python+QT+ffmpeg综合项目实战的需求和需要用到的库
    java8-Stream流常用API
    POJ1094Sorting It All Out题解
  • 原文地址:https://blog.csdn.net/qq_43575801/article/details/127672012