读取打包到JAR中的文件:常见问题与解决方案(文件在但是报错not find)

news2024/12/25 13:41:37

读取打包到JAR中的文件:常见问题与解决方案

在这里插入图片描述

喝淡酒的时候,宜读李清照;喝甜酒时,宜读柳永;喝烈酒则大歌东坡词。其他如辛弃疾,应饮高梁小口;读放翁,应大口喝大曲;读李后主,要用马祖老酒煮姜汁到出怨苦味时最好;至于陶渊明、李太白则浓淡皆宜,狂饮细品皆可。
—— 林清玄 《温一壶月光下酒》

在Java应用中,特别是在使用Spring框架时,常常需要从JAR文件中读取资源。这个操作在开发期间看起来很简单,因为文件系统直接可访问。然而,一旦应用被打包成JAR后运行,常见的文件访问方法就会失败,因为JAR文件内的资源不能像普通文件那样被直接访问。
在Java和Spring框架中,理解资源文件的正确处理尤为重要,尤其是当资源文件被包含在JAR包内时。下面,我们将分析一个常见的错误示例,以及如何通过更合适的方法来纠正这个问题。

错误的案例:直接使用File API读取Spring的注入资源

在使用Spring框架时,我们可能会尝试直接将使用@Value注解注入的Resource转换为File来处理。这在资源文件位于文件系统中时有效,但如果这些资源位于JAR包内,此方法将导致失败。

示例错误代码:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;

@Component
public class ResourceReader {
    
    @Value("classpath:assets/document-formats/onlyoffice-docs-formats.json")
    private Resource resourceFile;

    public void readFile() {
        try {
            File file = resourceFile.getFile();  // 这里会抛出IOException
            // 进一步处理文件...
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("Failed to access resource file", e);
        }
    }
}
错误原因:

在这里插入图片描述

在上述代码中,Resource.getFile()方法在资源文件位于JAR包内时会失败,因为JAR内的资源并不是一个真正的磁盘上的文件,而是JAR文件的一部分。因此,尝试获取其作为File对象会抛出IOException

常见问题说明

当将应用打包成JAR(Java ARchive)文件时,所有的类文件和资源文件都被封装在一个单一的文件中。许多开发者习惯使用类似于文件路径的方式来访问资源,如使用File类。这在开发阶段没有问题,因为资源文件直接位于文件系统上。但是,一旦资源被封装到JAR中,尝试以同样的方式访问这些资源会导致FileNotFoundExceptionNullPointerException,因为File类不能读取JAR内部的路径。

解决方案
1. 使用Class.getResourceAsStream()方法

Java提供了Class.getResourceAsStream(String path)方法,它能够从当前类的类路径中读取资源为InputStream。这个方法适用于任何形式的类路径资源,包括JAR文件内的资源。

InputStream is = MyClass.class.getResourceAsStream("/path/to/your/resource.txt");
if (is != null) {
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
        reader.lines().forEach(System.out::println);
    } catch (IOException e) {
        e.printStackTrace();
    }
} else {
    System.out.println("Resource not found");
}
2. 使用ClassLoader.getResourceAsStream()方法

Class.getResourceAsStream()类似,ClassLoader.getResourceAsStream()也提供了一种从类加载器的类路径中读取资源的方法。这个方法不需要从类的角度去定位资源,而是直接从类路径的根开始。

InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("path/to/your/resource.txt");
if (is != null) {
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
        reader.lines().forEach(System.out::println);
    } catch (IOException e) {
        e.printStackTrace();
    }
} else {
    System.out.println("Resource not found");
}
3. 使用Spring框架的Resource抽象

如果你在使用Spring框架,Spring提供了一个非常强大的资源抽象,通过Resource接口来统一处理资源。Spring可以通过ApplicationContext来访问资源,使用Resource接口可以非常灵活地处理各种资源类型。

@Autowired
private ResourceLoader resourceLoader;

public void readResource() {
    Resource resource = resourceLoader.getResource("classpath:path/to/your/resource.txt");
    try (InputStream is = resource.getInputStream()) {
        new BufferedReader(new InputStreamReader(is))
            .lines()
            .forEach(System.out::println);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
最佳实践
  • 使用流处理资源:无论资源位于文件系统还是JAR文件中,始终使用InputStream来访问资源。这样可以确保应用的可移植性和灵活性。
  • 优先使用Spring的Resource抽象:如果你使用Spring框架,利用Spring的Resource抽象来处理资源,这样可以更容易地集成更多Spring功能。
  • 错误处理:总是进行适当的错误处理,如资源不存在时的处理。这可以避免运行时错误并且精确定位错误点。

破问题太坑了——

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1660816.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Python爬虫实战入门】:教你一个程序实现PPT模版自由

文章目录 💥一、PPT模版爬取🔥1.1 第一个爬虫🚲1. 获取下载页面链接 ❤️1.2 第二个爬虫🚲1.3 第三个爬虫🎈2. 文件保存 ❤️1.4 翻页处理 🔥二、完整代码 🔥🔥🔥 Pytho…

双向链表(详解)

在单链表专题中我们提到链表的分类,其中提到了带头双向循环链表,今天小编将详细讲下双向链表。 话不多说,直接上货。 1.双向链表的结构 带头双向循环链表 注意 这几的“带头”跟前面我们说的“头节点”是两个概念,实际前面的在…

【神器来袭】快速解放双手,朋友圈自动转发工具,告别繁琐操作!

朋友圈作为一个重要的营销推广渠道,如果能实现自动转发,那对于很多企业或个人来说,是极好的。下面,就给大家分享一个实用且便捷的朋友圈运营工具——个微管理系统,让大家都能快速推广。 1、多账号登录,定时…

bcrypt.dll文件丢失怎么办?bcrypt.dll怎么修复?

在计算机系统运行过程中,如果发现无法找到或缺失bcrypt.dll文件,可能会引发一系列的问题与故障。首先,由于bcrypt.dll是系统中一个重要的动态链接库文件,它的主要功能可能涉及到系统核心服务、应用程序支持或者特定功能模块的运行…

python爬虫(三)之虎嗅网汽车文章爬虫

python爬虫(三)之虎嗅网汽车文章爬虫 闲来没事,闲鱼上有个好兄弟要我从虎嗅网上抓一些汽车文章的爬虫,于是大力出奇迹,我写了一个python程序,将这个网站上所有的汽车文章全部抓取下来了,存储到…

2024年记一次Mingw64-13.2.0编译Qt6.6.3,包含文档编译。

My C Development. 前言:不包含qtwebengine。 一、准备文件 (1)mingw64-13.2.0 下载链接:,ucrt64_13.2_ucrt_posix_rev6_msys2.7z【蓝奏云】。 (2)qt6.6.3源码 下载链接:Downlo…

电子版图书制作,一键转换可仿真翻页的画册

在数字化浪潮的冲击下,传统纸质图书逐渐被电子版图书取而代之。电子版图书以其便携、环保、更新快速等特点,吸引了越来越多的读者。制作一款既具备电子图书的便捷性,又能仿真翻页的画册,成为当下图书出版行业的新趋势 1.要制作电子…

微信小程序支付(完整版)-ThinkPHP/Uniapp

技术说明 1.前端:uniapp、vue3 2.接口:PHP8、ThinkPHP8、MySQL8.0 3.微信支付- PHP,官方示例文档 4.示例代码的模型及业务自己进行调整,不要一味的复制粘贴!!! 流程说明 1.小程序调用接口…

资源管理游戏模版进入The Sandbox

我们非常高兴地向您介绍 Game Maker 的最新模板:资源管理游戏! 这一全新的模板让您能够深入身临其境的游戏体验中,同时掌握令人兴奋的新机制。通过揭开模板的神秘面纱,您可以锤炼您的游戏设计技能。 什么是资源管理游戏&#xff1…

winpcap无法安装提示新版本已经安装-window11解决办法

winpcap无法安装提示新版本已经安装-window11解决办法 问题解决办法 问题 安装ensp的时候跳出来这个问题,说自己的winpcap没安装,建议安装 但当自己去安装一个winpcap的时候,它又跳出来这个! WinPcap 4.1.3 Setup A newer versi…

电脑设置在哪里打开?Window与Mac双系统操作指南

随着科技的不断发展,电脑已经成为我们日常生活和工作中不可或缺的一部分。然而,对于许多初学者来说,如何找到并熟悉电脑的设置界面可能是一个挑战。特别是对于那些同时使用Windows和Mac双系统的用户来说,更是需要一篇详尽的指南来…

android进阶-AIDL

参考:Android进阶——AIDL详解_android aidl-CSDN博客 AIDL(Android 接口定义语言),可以使用它定义客户端与服务端进程间通信(IPC)的编程接口,在 Android 中,进程之间无法共享内存&…

latex algorithm2e 库学习总结

案例1 \documentclass{article}\usepackage{xeCJK} \usepackage[]{algorithm2e} %\usepackage{ctex} % 中文包\begin{document}\renewcommand{\algorithmcfname}{算法} % 把标题设置为“算法” \begin{algorithm…

数据库管理-第184期 23ai:干掉MongoDB的不一定是另一个JSON数据库(20240507)

数据库管理184期 2024-05-07 数据库管理-第184期 23ai:干掉MongoDB的不一定是另一个JSON数据库(20240507)1 JSON需求2 关系型表设计3 JSON关系型二元性视图3 查询视图总结 数据库管理-第184期 23ai:干掉MongoDB的不一定是另一个JSON数据库(20…

雪花算法生成全局Id,看这篇就够了

分布式id 雪花算法能够生成一个64位long类型数据,适合做分布式系统的全局标识符,或者分库分表中,同类型数据表的主键 原理探究 雪花算法:以一台服务器为对象,在一毫秒时间内,生成一个自增的long数据特点…

Ps 滤镜:视频

Ps菜单:滤镜/视频 Filter/Video “视频”滤镜子菜单中包含了“NTSC 颜色”和“逐行”两个滤镜。 这两个滤镜都是针对视频和电视播放的特定需求设计的。 “逐行”滤镜主要解决交错视频的视觉问题,而“NTSC 颜色”滤镜则确保色彩在电视播放时的兼容性和准确…

springboot+vue+mysql老年大学会员管理系统+PPT+论文+讲解+售后

现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本老粘大学会员管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息&a…

HTML4(二)

文章目录 1 开发者文档2 基本标签2.1 排版标签2.2 语义化标签2.3 行内元素与块级元素2.4 文本标签2.5 常用标签补充 3 图片标签4 超链接标签4.1 跳转页面4.2 跳转文件4.3 跳转锚点4.4 唤起指定应用 5 列表5.1 有序列表5.2 无序列表5.3 自定义列表 6 表格6.1 基本结构6.2 表格标…

如何查看页面对应的Selenium定位参数

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…

IO 5.10

在一个进程中,创建一个子线程。 主线程负责:向文件中写入数据 子线程负责:从文件中读取数据 要求使用线程的同步逻辑,保证一定在主线程向文件中写入数据成功之后,子线程才开始运行,去读取文件中的数据#incl…