您当前的位置:首页 > 互联网教程

Java 读取resources下的资源文件

发布时间:2025-05-24 18:31:02    发布人:远客网络

Java 读取resources下的资源文件

一、Java 读取resources下的资源文件

1、在Web项目的resources目录中,常常需要存放配置文件和资源文件。本文总结了常用的文件读取方式,并说明了需要注意的细节。

2、为了使用FileUtils、IOUtils等工具类,需要引入commons-io jar包。

3、通过ClassLoader读取文件有两种方式:获取文件输入流和获取文件URL。使用ClassLoader.getResourceAsStream()即可。

4、使用Class读取文件时,同样有两种方式:获取文件输入流和获取文件URL。通过Class.getResourceAsStream()实现。

5、Class.getResourceAsStream()与ClassLoader.getResourceAsStream()的主要区别在于路径的处理。Class方法需要在文件路径前加一个"/"。

6、在Spring项目中读取文件时,ClassPathResource类的构造参数path无需绝对路径区分。无论使用"json/city_code.json"还是"/json/city_code.json",都能成功获取文件输入流。

7、面对是否需要在路径前加"/"的问题,应考虑使用的读取方法。通过Class读取文件时,路径需以"/"开始;通过ClassLoader或Spring提供的工具类读取文件则无需添加。

8、解决这些问题的最佳方法是查阅源码并进行断点调试,以理解各个读取文件方式之间的联系和差异。

9、以下是Class类两个方法的部分源码,通过分析源码可得出在使用这些方法读取文件时,路径处理方式存在差异。具体而言,通过Class读取文件时路径需以"/"开头,而通过ClassLoader或Spring工具类读取文件则无需添加。理解这些细节有助于正确使用相关API,高效完成资源文件读取任务。

二、java 代码里读取jar包下resources目录下的文件

在进行Java项目开发时,资源文件的读取是一个常见的需求,尤其是当这些文件被放置在resources目录下。然而,有时在将项目打包至Linux环境或部署到Tomcat服务器后,可能会遇到文件找不到的问题。本文将介绍几种在Java代码中读取resources目录下文件的方法,并通过实际操作来解答如何确保资源文件在各种环境中都能被成功访问。

在开始实践前,我们首先明确几个关键点:

1.**java.io.File**类:在IDEA开发环境中使用此方法时,文件路径的构建可能会出现问题,因此不推荐直接使用此方法进行资源文件读取。

2.**java.lang.ClassLoader#getSystemResourceAsStream**:此方法提供了从系统类加载器中获取资源文件的流,但在某些情况下,可能无法直接适用于项目中的资源文件读取。

3.**class.getClassLoader().getResourceAsStream**:通过当前类的类加载器获取资源文件流,这是一种通用且推荐的方法,适用于各种情况。

4.**org.springframework.core.io.FileSystemResource**:Spring框架提供的类,用于封装文件路径和资源读取,通常与Spring应用集成时使用。

5.**org.springframework.core.io.FileSystemResourceLoader**:同样来自Spring框架,用于加载文件系统中的资源,与Spring应用集成时可能更方便。

综合考虑以上方法,推荐使用**class.getClassLoader().getResourceAsStream("text.txt")**。这种方法不仅适用于直接的Java应用,也适用于集成Spring框架的项目。它能够确保在不同环境(如Linux、Tomcat服务器)下,资源文件都能被成功读取。

实践时,请确保资源文件的路径在调用方法时正确无误。例如,如果资源文件位于resources目录下,路径应为"text.txt"。通过这种方式,可以有效解决资源文件在不同环境下的访问问题,提高项目部署和运行的稳定性。

本文提供的实践方法和建议旨在帮助开发者解决在不同环境下读取Java项目中resources目录下文件的问题。若还有其他方法或有疑问,欢迎在评论区留言讨论。

三、Java try-with-resources 特性详解

1、大家好,我是磊磊落落,目前我在技术上主要关注:Java、Golang、架构设计、云原生和自动化测试。欢迎来我的博客( leileiluoluo.com)获取我的最近更新!

2、Java 7中引入了try-with-resources特性来保证资源使用完毕后,自动进行关闭。任何实现了 java.lang.AutoCloseable接口的类,都可以看作是资源,也都可以使用该特性。本文将详细介绍该特性的使用方法与注意事项。

3、传统的 try-finally手动资源关闭

4、Java 7之前,资源使用完毕后,需要在finally块中手动对其进行关闭。

5、可以看到,如上测试用例尝试从resources文件夹下的文件 test.txt里读取一行内容。用到了 FileReader与 BufferedReader文件流类,使用完毕后,在 finally块内进行了关闭操作。

6、传统的 try-finally手动资源关闭存在的问题

7、上面演示的这种在try-finally块进行资源使用及手动关闭的方式存在几个问题:

8、下面就对这几个问题进行一一说明。

9、容易忘记关闭资源,从而引发内存泄漏

10、把资源关闭的事情交给开发人员自己手动处理的话,就容易发生忘记的情形。一旦忘记关闭,资源就会一直被认为在引用,垃圾收集器就无法对其进行回收,最终可能会引发内存泄漏问题。

11、资源比较多的时候,代码嵌套层次较深,代码可读性不佳

12、对多个资源进行操作的时候,就可能会嵌套多个try-finally块,代码可读性会因此大大降低。

13、try块与 finally块同时发生异常时,存在异常压制问题

14、因try块与 finally块内都有可能发生异常,那同时发生异常的时候,最终抛出的是哪个异常?

15、我们可以对上面的代码稍微改一下:假设传一个不存在的文件地址,然后finally块内的资源进行手动关闭时也没有进行非 null判断。

16、运行时,发生异常,异常信息如下:

17、调试一下,发现因传入的文件路径不存在,首先会在try块内抛出 FileNotFoundException;进入 finally块后,调用 fr.close()时,发现 fr并未初始化完成,是 null值,会抛出 NullPointerException;但最终只直接展示 NullPointerException,FileNotFoundException被压制了。

18、如果想要获取被压制的异常,还需自行对最终异常进行捕获,并调用e.getSuppressed()来获取被压制的异常信息。

19、3 Java 7:try-with-resources自动资源关闭

20、使用 Java 7try-with-resources特性可以省去编写手动关闭资源的代码,即 try块内的语句执行完成时,资源将自动进行关闭。

21、可以看到,如上测试用例中,将FileReader与 BufferedReader的声明与创建,放在了 try括号内,这样即可以无需手动进行资源关闭了。

22、这其实是一个语法糖,使用该特性时,编译器会自动为我们添加调用close方法关闭资源的代码。

23、我们将生成的.class文件反编译一下,即可以看到编译器到底帮我们添加了哪些逻辑:

24、可以看到,编译器使用传统的try-finally写法贴心的为我们添加了资源关闭的代码,而且资源关闭的顺序是:try括号内先声明的资源后关闭,后声明的资源先关闭。而且关闭资源时,若发生异常,其会将其压制,而抛出 try-with-resources块内发生的异常。

25、4 Java 7:try-with-resources自动资源关闭具备的优点

26、改用try-with-resources后的几个优点:

27、5 Java 9对 try-with-resources特性的增强

28、从上面的例子可以看到,Java 7使用try-with-resources时,资源的声明与创建必须在 try-with-resources块内进行。

29、而自 Java 9起,资源的声明与创建可以移出到try-with-resources块外,而仅需将引用资源的变量放在 try-with-resources块内即可。

30、6自定义 AutoClosable资源的实现

31、文章开头即提到,不仅是 Java内置的资源(诸如InputStream、OutputStream与 java.sql.Connection等)可以使用 try-with-resources特性,只要是实现了 AutoClosable接口的资源,都可以使用该特性。

32、下面就自定义一个AutoClosable资源的实现,然后对该自定义资源使用一下 try-with-resources特性。

33、可以看到,实现AutoCloseable接口,只需要实现 close方法即可,自定义资源与内置资源在 try-with-resources特性的使用上并无差别。

34、综上,本文首先介绍了在try-with-resources特性引入前,资源的关闭是如何做的;然后介绍了 try-with-resources特性如何使用,以及其带来的好处;最后介绍了 Java 9对 try-with-resources特性的增强以及自定义 AutoClosable资源的实现。

35、本文所涉及的所有示例代码已托管至本人 GitHub,欢迎关注或 Fork。

36、参考资料 [1] Creating and Destroying Objects: Prefer try-with-resources to try-finally| Effective Java(3rd Edition), by Joshua Bloch [2] The try-with-resources Statement(The Java™ Tutorials)| Oracle- docs.oracle.com [3] Java Language Changes for Java SE 9: More Concise try-with-resources Statements| Oracle- docs.oracle.com [4] Java Try With Resources| Jakob Jenkov- jenkov.com [5] Is try-with-resource not safe when declaring multiple effectively final resources?| Stackoverflow- stackoverflow.com [6] Java try-with-resources example| Mkyong- mkyong.com