如何从JAR的类路径读取文件?原WAR可行代码在JAR中报错
解决JAR中读取类路径资源的FileNotFoundException问题
这种情况我碰到过好多次——当资源从WAR的文件系统环境移到JAR的归档环境时,getFile()方法直接就失效了,核心原因很直白:JAR里的资源不是文件系统中的真实物理文件,而是嵌入在压缩包内的字节流,根本没法通过java.io.File对象来访问。
为什么原来的代码在WAR里能正常运行?
WAR文件在服务器部署时一般会被解压到本地文件系统,src/main/resources下的文件会变成实实在在的物理文件,所以getFile()能找到对应的绝对路径。但JAR是一个完整的压缩包,里面的资源没有对应的文件系统路径,调用getFile()自然会抛出找不到文件的异常。
正确的解决方案:直接读取资源输入流
我们需要绕开File对象,直接从类路径中读取资源的字节流,这里有两种常用的靠谱方式:
方式1:用Spring的ClassPathResource读取流
既然你已经在使用Spring的ClassPathResource,直接用它的getInputStream()方法就行,搭配Apache Commons IO的IOUtils可以快速把流转成字节数组:
import org.springframework.core.io.ClassPathResource; import org.apache.commons.io.IOUtils; import java.io.InputStream; import java.io.IOException; // 读取资源内容 try (InputStream inputStream = new ClassPathResource("project.txt").getInputStream()) { byte[] content = IOUtils.toByteArray(inputStream); // 在这里处理你的字节数组内容 } catch (IOException e) { // 异常处理,比如资源不存在时的提示 e.printStackTrace(); }
如果不想依赖第三方库,也可以手动读取流:
try (InputStream inputStream = new ClassPathResource("project.txt").getInputStream()) { byte[] buffer = new byte[inputStream.available()]; inputStream.read(buffer); // 处理读取到的buffer内容 } catch (IOException e) { e.printStackTrace(); }
方式2:用Java原生类加载器读取流
如果你的代码不想依赖Spring,也可以用Java原生的类加载器方法:
import java.io.InputStream; import java.io.IOException; import org.apache.commons.io.IOUtils; try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("project.txt")) { if (inputStream == null) { throw new IOException("Resource project.txt not found in classpath"); } byte[] content = IOUtils.toByteArray(inputStream); // 处理读取到的内容 } catch (IOException e) { e.printStackTrace(); }
额外注意点
- 确保
project.txt确实在JAR的类路径根目录:src/main/resources下的文件编译后会被打包到JAR的根路径,如果你的资源在子目录(比如src/main/resources/config/project.txt),路径要写成config/project.txt。 - 一定要用
try-with-resources语法,它会自动帮你关闭输入流,避免资源泄漏问题。
内容的提问来源于stack exchange,提问作者Jelly Orns
相关产品推荐
相关产品推荐

