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