weixin_44637331 2022-10-13 16:36 采纳率: 100%
浏览 38
已结题

Jar下获取File对象问题

【需求:】 Java 获取配置文件File对象,且 jar 包方式运行无误

这里先给出错误代码,以及个人思路:

方式1 : new File(path)
目录结构:

img

    public static void main(String[] args) {
        File file = new File("src/main/resources/words.txt");
        System.out.println(file.getAbsolutePath());
        System.out.println(file.exists());
    }

开发环境下执行,但打包成jar 情况下,无法执行 ---> 找不到文件,且资源文件已经在jar中了,只不过位置变量如果使用 File file = new File("classes/words.txt"); Jar下可以执行,但Idea开发环境下不能执行。

方式2:ClassLoader

    public static void main(String[] args) {
        URL url = ClassLoader.getSystemClassLoader().getResource("words.txt");
        String filePath = url.getFile();
        File file = new File(filePath);
        System.out.println(file.exists());
    }

结果根上面的一样,Idea开发环境下可以获取文件 (file.exists() = > true ) , 而 jar 包下 找不到文件(file.exists() = > false),并且在jar下运行时,如果获取file的绝对路径为:F:\desktop\untitled2\target\file:\F:\desktop\untitled2\target\untitled2-1.0-SNAPSHOT.jar!\words.txt 很奇怪。

方式3:ClassLoader -> stream

    public static void main(String[] args) throws IOException {
        URL url = ClassLoader.getSystemClassLoader().getResource("words.txt");
        InputStream inputStream = url.openStream();
        System.out.println(inputStream.available());
        inputStream.close();
    }

这种方式 开发环境和jar环境下都可以,但不符合我的需求。我需要的配置文件的File对象。这里是文件流,估计有人会质疑我这个需求》。,其实我也是无赖之举,项目引用的第三方包的某个功能方法的参数入口就是个File类型的对象获取直接 string类型的url。

其他:我还尝试过 spring 的 ResourceUtils.getFile 工具方法,也是一样(开发IDEA环境下,可以获取到文件。但在Jar环境下就获取不到了)。有没有什么方式可以获取配置文件的File对象

我的思考想法
  1. 方式3中能够获取文件输入流比较令我深思,我们平常获取文件流之前想要先获取到该文件File对象才行吧。那么说明方式3中应该获取了File文件对象,然后才获取它的文件流并返回,但它是怎么成功获取File文件对象的呢?。
  2. 在设计api的时候是不是应该避免设计为File类型的参数哦,如果将File类型的参数换成 stream 的话好像也不好,因为这个想要close,不好把控close的时机,这里有什么别的建议码?。
  3. java 打包成Jar包后,项目的目录结构与Jar包中的目录结构是不同的,所以项目中获取文件不能像方式1那样写。如果要改,该怎么改呢?难道这里还要区分环境? 开发使用src/main/resources/words.txt,部署生产环境使用classes/words.txt ,感觉这不是一个聪明的方式,这里还是什么其他思路码?。
  • 写回答

2条回答 默认 最新

  • a1767028198 2022-10-14 09:08
    关注

    恕我直言,接口设计之初就不应该考虑使用file,优先inputStream和byte[],如果你这里的接口没有提供这两个参数的重载方法,固定死了只能走file对象,那就只能曲线救国了,PathMatchingResourcePatternResolver去classpath下扫描文件,扫描结果单个文件是Resouce,Resource可以直接获取URL,此时可以直接判断你这个资源是在jar包中还是在文件夹中(war包搭配外置tomcat的方式)

    img


    如果这个值是jar,自己把文件复制到服务器的指定位置,file对象就有了

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 10月25日
  • 已采纳回答 10月17日
  • 修改了问题 10月13日
  • 修改了问题 10月13日
  • 展开全部

悬赏问题

  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
  • ¥15 linux驱动,linux应用,多线程