在运行jar包中正确读取资源文件

2023-05-16

可能有不少初学者会有这样的困惑:在你的代码里调用了一些资源文件,如图片,音乐等,在调试环境或单独运行的时候可以正常显示或播放,而一旦打包到jar文件中,这些东东就再也出不来了,除非把这个jar放到原来未打包以前的目录下,但通常jar是单独发布的。这里介绍一个解决这类问题的方法。
getResource和getResourceAsStream
    问题的根源还是在于老生常谈的所谓class path,不信的话你在系统环境变量里的ClassPath加上你的jar文件,这下你就看得到你的图片了!但单独发布jar的话不可能指望每次都让用户为你的jar而专门修改classpath。那么有没有什么办法一劳永逸地搞定它呢?我们需要从类的装载入手。先扯远一点,在开发JSP之类的Web应用程序的时候要用到第三方的库怎么办?通常的做法是把这些库(可以是class,也可以是jar)统统放到WEB-INF/lib/目录下面,为什么这样系统就认了呢?因为Web容器(譬如Tomcat)在装载类的时候有自己的组织方式(可以参考Tomcat手册http://jakarta.apache.org/tomcat/tomcat-4.1-doc/class-loader-howto.html)。特别地,jar也是类装载器的一个可访问媒介,ClassLoader提供了两个方法用于从装载的类路径中取得资源:
public URL getResource(String name);
public InputStream getResourceAsStream(String name);

这里name是资源的类路径,它是相对与“/”根路径下的位置。getResource得到的是一个URL对象来定位资源,而getResourceAsStream取得该资源输入流的引用保证程序可以从正确的位置抽取数据。
真正使用的不是ClassLoader的这两个方法,而是Class的getResource和getResourceAsStream方法,因为Class对象可以从你的类得到(如YourClass.class或YourClass.getClass()),而ClassLoader则需要再调用一次YourClass.getClassLoader()方法,但根据JDK文档的说法,Class对象的这两个方法其实是“委托”(delegate)给装载它的ClassLoader来做的,所以只需要使用Class对象的这两个方法就可以了。
在参考资料中有一篇老外写的文章比较深入介绍了从jar中装载资源的方法。

    一个应用的例子

以下是在我写的一个小工具MSNHistoryCombiner中用到的一段代码,可以从jar中装载图片和文本信息。譬如,你的jar中根目录下有个img目录,里面放有一些图片,如img1.jpg,你可以这样调用
Utilities.getImageFromJar("/img/img1.jpg", YourClass.class);
注意必须这里是“/img/img1.jpg”而非“img/img1.jpg”。从jar中读文本资源也是类似方法调用getTextFromJar。
需要说明的是,这段代码也不是我原创的,是从一段别的代码中经过修改得到的,但原代码的来源忘记了,在这里向原作者表示感谢和歉意。

import java.awt.Image;
import java.awt.Toolkit;
import java.io.*;

public class ResourseReader {

public ResourseReader() {
}

public static Image getImageFromJar(String s, Class class1) {
Image image = null;
InputStream inputstream = class1.getResourceAsStream(s);
if(inputstream != null) {
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
try {
byte abyte0[] = new byte[1024];
for(int i = 0; (i = inputstream.read(abyte0)) >= 0;) {
bytearrayoutputstream.write(abyte0, 0, i);
}

image = Toolkit.getDefaultToolkit().createImage(bytearrayoutputstream.toByteArray());
}
catch(IOException ioexception) {
ioexception.printStackTrace();
}
}
return image;
}

public static String getTextFromJar(String s, Class class1) {
String s1 = "";
InputStream inputstream = class1.getResourceAsStream(s);
if(inputstream != null) {
BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(inputstream));
String s2;
try {
while((s2 = bufferedreader.readLine()) != null) {
s1 = s1 + s2 + "\n";
}
}
catch(IOException ioexception) {
ioexception.printStackTrace();
}
}
return s1;
}
}


从Jar中读取gif文件


在Java的程序发布中,很多人会选择采用二进制的jar的格式进行发布,怎么样读取Jar里面的资源呢?
主要是采用ClassLoader的下面几个方法来实现:
public URL getResource(String name);
public InputStream getResourceAsStream(String name)

public static InputStream getSystemResourceAsStream(String name)
public static URL getSystemResource(String name)

后两个方法可以看出是静态的方法,这几个方法都可以从Jar中读取图片资源,但是对与动画的gif文件,笔者在尝试过程中发现,存在一些差异。

String gifName为Gif文件在Jar中的相对路径。
(1)使用了两个静态方法
BufferedImage image=ImageIO.read(ClassLoader.getSystemResourceAsStream(gifName));

或者

Image image=Toolkit.getDefaultToolkit().getImage(ClassLoader.getSystemResource(gifName));

这两种方式可以成功地读取gif文件,但是对于gif动画,显示出来地是静态的。

(2)使用其他两个方法
Image image=Toolkit.getDefaultToolkit().getImage(this.getClass.getClassLoader().getResource(gifName));

再这种方式下动画可以正常显示了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在运行jar包中正确读取资源文件 的相关文章

  • 对于MyBatis框架的学习

    1 MyBatis MyBatis 它是Apache的一个开源项目 iBatis 2010年这个项目由apache software foundation 迁 移到了google code xff0c 并且改名为MyBatis 2013年1
  • Spring Boot 原理的分析(超详细!!!)

    1 Spring Boot Spring Boot 没有特定的业务 xff0c 将其他框架进行整合 xff0c 去掉配置 开箱即用 Spring Boot 跟 Spring MVC 的整合 Spring Boot 跟 Thymeleaf 的
  • 多线程进阶=> JUC并发编程(超详细!)

    多线程进阶 61 gt JUC并发编程 1 什么是JUC java util 工具包 xff08 包 分类 xff09 业务 xff1a 普通的线程代码 Thread Runnable 没有返回值 效率相比于 Callable 相对较低 x
  • @Data 注解在实体类的使用可省去生成GET,SET方法

    描述 xff1a 使用lombok插件省去实体类生成GET xff0c SET方法 使用步骤 xff1a 1 打开intellij idea开发工具 File Settings Plugins xff0c 在右侧单击 Browse repo
  • Android ViewBinding的使用详解

    一 什么是view binding 视图绑定会替代 findViewById 通过视图绑定功能 xff0c 您可以更轻松地编写可与视图交互的代码 在模块中启用视图绑定之后 xff0c 系统会为该模块中的每个 XML 布局文件生成一个绑定类
  • 对树结构的学习

    树的常用术语 节点 xff0c 树中的一个连接点 父节点 xff0c 若一个节点含有子节点 xff0c 则这个节点成为其子节点的父节点 子节点 xff0c 一个节点含有的子树的根节点成为该节点的子节点 节点的权 xff0c 节点的具体值 节
  • 对Redis数据库的学习!

    Redis的学习 1 Nosql概述 为什么要用Nosql 1 单击MySQL的年代 90年代 xff0c 一个基本的网站访问量一般不会太大 单个数据库完全足够 那个时候 更多的去使用静态网页Html 服务器根本没有太大的压力 思考一下 这
  • 常用设计模式的学习

    1 设计模式 1 1概述 xff1a 软件设计模式 xff08 Software Design Pattern xff09 xff0c 又称设计模式 xff0c 是一套被反复使用 多数人知晓的 经过分类编目的 代码设计经验的总结 它描述了在
  • Archlinux + Gnome 安装教程

    1 制作装机工具 Ventoy 2 下载 archlinux 镜像 archlinux 种子文件 3 选择U盘启动 Ventoy 4 步骤 span class token comment 更新系统时间 span timedatectl s
  • HTTP请求:java.io.IOException: Server returned HTTP response code: 405 for URL

    写Http请求的时候报405 报错如下 xff1a 错误码405 xff1a 表示不允许此方法 xff1a 对于请求所标识的资源 xff0c 不允许使用请求行中所指定的方法 常用的几个方法 xff1a GET POST PUT DELETE
  • MongoRepository的 findAll(Example example, Pageable )的使用方法

    Example example 61 Example of 实体类 xff0c ExampleMatch package com xuecheng manage media service import com xuecheng frame
  • nginx反向代理解决外网端口膨胀的问题

    问题 xff1a 现在很多涉及到第三方回调我们接口的情况 我们不能无限制的开通外网端口的映射 xff08 需要提流程 xff09 解决方案 xff1a 基于nginx对一个映射过外网的端口进行反向代理 实例如下 server listen
  • 2014流水账

    欢迎转载 xff0c 转载请注明出处 本文地址 xff1a http blog csdn net zhenggaoxing article details 42386821 三天元旦小长假结束了 xff0c 先来回顾下三天的假期 xff1a
  • IOS中文排序学习

    前言 xff1a 最近有中文排序的需要 xff0c 发现系统没有提供中文排序的方法 xff0c 于是参考学习了网上前辈的代码实现了中文排序功能 xff0c 本文记录的就是学习实现中文排序的过程 实现英文排序 系统提供了英文排序的方法 写了一
  • IOS 定制中间突出UItabBar

    前言 xff1a 公司的项目需要定制一个中间突出的TabBar xff0c 在github 上找到一份可以参考的代码 xff08 虽然是四年前的 xff0c 但是还是很有参考价值 xff09 网址 xff1a https github co
  • intellj idea打包jar

    描述 xff1a 用 intellj idea 工具打包java项目 jar 步骤 xff1a 1 xff1a File Project Structure 2 xff1a 图中 1 部分要选择main方法所在的类 xff0c 2 部分要注
  • Xcode删除所有断点

    问题是这样的 xff1a 接手新的项目 xff0c 顿时吓尿了 xff1a 整个程序有无数个断点 xff0c 那么如何一次性删除呢 xff1f 如下图 xff1a 点击Belete Breakpoints 就可以了
  • TortoiseSVN使用教程[多图超详细]

    安装及下载client 端 下载Windows 端程序 xff1a http tortoisesvn net downloads 一般而言 xff0c 如果是32 bit的Windows XP 应该使用TortoiseSVN 1 4 x x
  • 将UIColor转换为RGB值

    objc view plain copy 将UIColor转换为RGB值 NSMutableArray changeUIColorToRGB UIColor color NSMutableArray RGBStrValueArr 61 NS
  • 业余时间你在做什么,你就会变成什么样的人?

    改变 xff0c 从业余时间开始 博客定位 xff1a 技术 43 思考 其余统统不要 2017 xff0c 我来了 xff01

随机推荐

  • Xcode9 无证书真机调试

    写在前面 公司分配了新的测试机 证书99台名额已满 所以上网找教程 学习了一下如何使用Xcode无证书进行真机调试 一 创建证书 1 运行Xcode xff0c Xcode Preference 添加账号 xff08 能在appstore下
  • HTML知识点

    这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题 xff0c 有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中 居左 居右SmartyP
  • SpringCloud:seata 服务端启动以及介绍(1)

    SpringCloud xff1a seata 服务端启动以及介绍 文章目录 SpringCloud xff1a seata 服务端启动以及介绍关联文章1 seata是什么1 1 四种事务模式1 2 三种角色 2 启动seata 服务端 x
  • 简单审批流程表设计

    审批配置表 xff08 approval config xff09 字段名称 类型 长度 约束 备注 code varchar 64 not null 审批流程code type tinyint 1 not null 审批方式 xff1a
  • 学习笔记—— unreferenced local variable

    file c xff08 xff09 warning C 39 xxx 39 unreferenced local variable 变量XXX定义了 但是在程序中没有使用到 发出的一则警告 目前来看 xff0c 不影响程序的运行
  • STM32定时器配置为编码器模式(转)

    文章目录 一 编码器原理 二 为什么要用编码器 三 STM32编码器配置相关 四 STM32实战代码 五 一些注意 参考 一 编码器原理 如果两个信号相位差为90度 xff0c 则这两个信号称为正交 由于两个信号相差90度 xff0c 因此
  • java实现倒计时

    package timer import java util Calendar import java util Date import java util Timer import java util TimerTask java演示倒计
  • linux终端字符串转字符画

    概述 xff1a 将字符串 xff08 非图像 xff09 转换成字符画 xff0c 效果如图 xff1a lt
  • fastboot -- 如何刷系统中各个img文件

    Android系统adb刷机 作者 xff1a 郑鹤翔 在android的各个可用软件中 xff0c adb fastboot是最常用的一种 xff0c 作为开发人员 xff0c 我们需要经常的进行内核 xff0c 系统代码等的修改 xff
  • AndroidStudio Kotlin项目搭建

    简介 xff1a 本文主要先大概介绍一下怎么在as上搭建kotlin项目 xff0c 然后主要具体介绍kotlin的语法 安装kotlin plugin 在AS 3 0及以后的版本是自带Kotlin plugin的 xff0c 但是如果你现
  • Mariadb安装之后的各种设置

    1 启动MariaDB 安装完成MariaDB xff0c 首先启动MariaDB xff0c 两条命令都可以 systemctl start mariadb 或者 service mariadb start 设置开机启动 systemct
  • python读取文件失败解决方案

    python读取文件失败解决方法 我的目录如下 python text files pi digits txt python text files file reader py 1 python默认读取当前根目录 注意 Linux 目录间用
  • from matplotlib.cbook import is_string_like, el ImportError: cannot import name 'is_string_like'

    Traceback most recent call last File 34 321 py 34 line 2 in lt module gt import matplotlib pyplot as pt File 34 C Progra
  • STM32F4XX 采集编码器的溢出处理

    STM32F4XX定时器16位 xff0c 采集编码器时候会在0xFFFF溢出 xff08 假设配置period 61 0xFFFF xff09 假设不溢出的情况下1ms之内编码器变化的最大范围小于0x7FFF xff0c 则关于溢出则可以
  • dependencyManagement和dependencies的区别

    dependencyManagement和dependencies的区别 参考 xff1a http zhaoshijie iteye com blog 2094478 pom xml中build标签 cpf2016的博客 CSDN博客 还
  • VScode播放网易云音乐(详细讲解)

    步骤 安装插件 xff1a VSC Netease Music 按shift 43 ctrl 43 p xff0c 输入 nete 出现下图 在按shift 43 ctrl 43 p xff0c 输入 nete 即可选择播放音乐 xff08
  • 安装和配置openssl

    Steps to download compile and install are as follows Note Replace 0 9 8e with your version number Downloading OpenSSL Ru
  • 自定义异常的使用

    下面是定义一个自定义异常的例子 xff0c 开发中可以以此作为参考 xff0c 根据项目需求编写自己的异常类 package com thinkgem wlw modules job service 自定义异常要继承 Exception 类
  • Ant中的classpath配置和使用

    Ant手册中配置classpath采用classpath标签 xff0c 可是我发现这样配置总是不好用 xff0c 还是直接用path设置classpath 一 xff09 设置classpath的方法 lt path id 61 34 p
  • 在运行jar包中正确读取资源文件

    可能有不少初学者会有这样的困惑 xff1a 在你的代码里调用了一些资源文件 xff0c 如图片 xff0c 音乐等 xff0c 在调试环境或单独运行的时候可以正常显示或播放 xff0c 而一旦打包到jar文件中 xff0c 这些东东就再也出