你知道怎么从jar包里获取一个文件的内容吗
背景
项目里需要获取一个excle文件,然后对其里的内容进行修改,这个文件在jar包里,怎么尝试都读取不成功,但是觉得肯定可以做到,因为项目里的配置文件就可以读取到,于是开始了探索之路。
报错的代码
ExcelWriter excelWriter = EasyExcel.write("to.xlsx").withTemplate(t).build();
我想要成功调用以上的方法,需要读取一个文件的内容,然后写入到另一个文件中
withTemplate的参数可以是String类型的文件路径,File类型和InputStream类型的,具体如下:

现在的问题就是如何一个正确的参数,能使它工作
原先的写法
因为项目都是以jar包的形式运行,所以需要获取jar包里文件的地址
有两种获取资源的方法,第一种就是Class.getResource(),第二种就是ClassLoader.getResource()
于是有了如下的第一版写法:
public class Main {
public static void main(String[] args) throws IOException {
URL url = Main.class.getResource("/Template.xlsx");
File file = new File(url.getFile());
ExcelWriter excelWriter = EasyExcel.write("to.xlsx").withTemplate(file).build();
excelWriter.finish();
}
}
文件的位置如下:

本地测试是没有问题的,但是一打包运行后就报如下的错误:
Caused by: java.io.FileNotFoundException: File 'file:/Users/xxx/spring-boot-study/target/classes/Template.xlsx' does not exist
定位到如下问题:

编写测试类
public class JarFileMain {
public static void main(String[] args) {
printFile(JarFileMain.class.getResource("/Template.xlsx"));
}
private static void printFile(URL url) {
if (url == null) {
System.out.println("null null");
return;
}
File file1 = new File(url.getFile());
System.out.println(file1 + " " + file1.exists());
File file2 = new File(url.toString());
System.out.println(file2 + " " + file2.exists());
}
}
直接这样运行是没有问题的,输出结果如下:
/Users/xxx/spring-boot-study/target/classes/Template.xlsx true
file:/Users/xxx/spring-boot-study/target/classes/Template.xlsx false
但是打成jar包后,运行结果如下:
java -cp /Users/xxx/spring-boot-study/target/spring-boot-study-1.0-SNAPSHOT.jar cn.eagleli.java.resource.JarFileMain
file:/Users/xxx/spring-boot-study/target/spring-boot-study-1.0-SNAPSHOT.jar!/Template.xlsx false
jar:file:/Users/xxx/spring-boot-study/target/spring-boot-study-1.0-SNAPSHOT.jar!/Template.xlsx false
可以看出没有打成包的时候,文件是存在的;但是打包后运行时,文件就不存在了。
找原因
因为项目里的config.xml文件里有一些配置信息的,而且它是读取成功的,所以肯定是由办法读取到内容的,于是就看了这部分的代码。
核心代码如下:
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
public class ClassPathConfigPropertySource implements PropertySource {
private XMLConfiguration config;
public ClassPathConfigPropertySource() {
try {
config = new XMLConfiguration(ClassPathConfigPropertySource.class.getClassLoader().getResource("config.xml"));
config.setReloadingStrategy(new FileChangedReloadingStrategy());
} catch (ConfigurationException e) {
}
}
@Override
public void setProperty(String key, Object value) {
if (config != null) {
config.setProperty(key, value);
}
}
@Override
public Object getProperty(String key) {
if (config != null) {
return config.getProperty(key);
}
return null;
}
}
于是就开始阅读XMLConfiguration这个类构造函数是怎么初始化的
读取文件内容的核心代码如下:
public abstract class AbstractFileConfiguration extends BaseConfiguration implements FileConfiguration {
public void load(URL url) throws ConfigurationException
{
if (sourceURL == null)
{
if (StringUtils.isEmpty(getBasePath()))
{
// ensure that we have a valid base path
setBasePath(url.toString());
}
sourceURL = url;
}
// throw an exception if the target URL is a directory
File file = ConfigurationUtils.fileFromURL(url);
if (file != null && file.isDirectory())
{
throw new ConfigurationException("Cannot load a configuration from a directory");
}
InputStream in = null;
try
{
in = url.openStream();
load(in);
}
catch (ConfigurationException e)
{
throw e;
}
catch (Exception e)
{
throw new ConfigurationException("Unable to load the configuration from the URL " + url, e);
}
finally
{
// close the input stream
try
{
if (in != null)
{
in.close();
}
}
catch (IOException e)
{
getLogger().warn("Could not close input stream", e);
}
}
}
}
可见它没有把URL转为File,而是直接用的InputStream in = url.openStream();
最终代码
public class Main {
public static void main(String[] args) throws IOException {
URL url = Main.class.getResource("/Template.xlsx");
//File file = new File(url.getFile());
ExcelWriter excelWriter = EasyExcel.write("to.xlsx").withTemplate(url.openStream()).build();
excelWriter.finish();
}
}
你知道怎么从jar包里获取一个文件的内容吗的更多相关文章
- 直接修改别人jar包里面的class文件 工具:jclasslib
出于某些原因 需要把别人jar包里面的class修改一下信息 配置文件*.properties MANIFEST.MF 这些东西可以直接用记事本打开修改 然后替换掉就OK.. 在网上游荡了半天,没有找 ...
- 替换Jar包中的一个文件 Replace a file in a JAR
例如: jar uf myJarFile.jar com\vsoft\servlet\myServlet.class This will replace the class myServlet.cla ...
- 项目jar包管理,使用 .userlibraries 文件增加jar包的可移植性,明确jar包依赖,多项目共用jar包里
当一个普通的项目,在不适用maven 等jar包管理工具的时候,通常我都会直接把jar 包复制lib下,并且在build path 中直接添加额外jar包,或者使用user_libraries包所用的 ...
- SpringBoot的配置文件加载顺序以及如何获取jar包里的资源路径
一.读取配置文件的四种方式 这四种配置文件放置方式的读取优先级依次递减,具体可以查看官方文档. 1.1jar包同级目录下的config文件夹里的配置文件 其实我以前就见过这种方式了,只是不知道怎么做的 ...
- PHP通过php-java-bridge调用JAVA的jar包里class类
正 文: 有的时候我们需要在PHP里调用JAVA平台封装好的jar包里的class类和方法,一般飘易推荐的做法是采用php-java-bridge做桥接,本文就来介绍一下大致的实现方法. 先简单说 ...
- jar包里查找指定的class文件,排查是否存在或重复,工具软件:Java Class Finder
jar包里查找指定的class文件,排查是否存在或重复,工具软件:Java Class Finder 1,下载工具地址:www.idesksoft.com/classfinder.html,如图: 2 ...
- Java读取其他jar包里的配置文件
最近要做个东西,需要自己控制数据库的事物,项目封装的框架,实在是提不起去阅读的兴趣, 就想直接去读框架的底层实现里面的数据连接的配置文件(如:Url,port,username,password等), ...
- 更新jar包里的配置文件
更新jar包里的配置文件 起因 从笔记本传了个jar到服务器,运行的时候才发现配置文件一个ip项填错了.本来很简单的问题,maven重新打包就可以了,但是30多M的jar包就因为一个配置项错了又要重新 ...
- Java 操作jar包工具类以及如何快速修改Jar包里的文件内容
需求背景:写了一个实时读取日志文件以及监控的小程序,打包成了Jar包可执行文件,通过我们的web主系统上传到各个服务器,然后调用ssh命令执行.每次上传前都要通过解压缩软件修改或者替换里面的配置文件, ...
随机推荐
- go中导入包的几种方式
标准方式: import ( "fmt" )使用:fmt.Println() 点(.)方式 import ( . "fmt" ) 使用时候,可以胜率fmt前缀P ...
- freeswitch刷新网关方法
1.freeswitch xml配置文件新增网关后,使其生效,可以重启freeswitch或者使用命令方式 fs_cli -H 127.0.0.1 -P 8021 -p hmzj -x sofia p ...
- 跨 Docker 宿主机 macvlan 类型
跨 Docker 宿主机 macvlan 类型 前言 a. 本文主要为 Docker的视频教程 笔记. b. 环境为 三台 CentOS 7.0 虚拟机 (Vmware Workstation 15 ...
- Java on Visual Studio Code的更新 – 2021年8月
Nick Senior Program Manager, Developer Division at Microsoft 大家好,欢迎来到 8 月版的 Visual Studio Code Java ...
- 我下载了python所有包,用以备份,有需要的自提
1.背景 我最近准备把1985年-2019年的全国30m分辨率土地利用数据按照地级市进行裁剪与归纳,这需要用到Geopandas对shp数据进行批量操作.在安装Geopandas的python包时,遇 ...
- css 限制字数
text-overflow: ellipsis; overflow: hidden; 不过需设置宽高
- 如何使用SQL的备份文件(.bak)恢复数据库
出于很多情况,数据库只剩下.bak文件,想要恢复数据库,找了很多资料才知道可以这样!!!!! 个人觉得图片教程更有意义,请看步骤: 1.选中"数据库" 右击 选择"还原数 ...
- css 参考手册 部署到本地
* 到css参考手册网站 http://css.doyoe.com/ 下载chm手册 * 到github下载对应的html页面 cd /Applications/XAMPP/htdocs git cl ...
- [科技]Loj#6564-最长公共子序列【bitset】
正题 题目链接:https://loj.ac/p/6564 题目大意 给两个序列\(a,b\)求它们的最长公共子序列. \(1\leq n,m,a_i,b_i\leq 7\times 10^4\) 解 ...
- 华为云计算IE面试笔记-请描述华为容灾解决方案全景图,并解释双活数据中心需要从哪些角度着手考虑双活设计
容灾全景图: 按照距离划分:分为本地容灾 同城容灾 异地容灾 本地容灾包括本地高可用和本地主备.(本数据中心的两机房.机柜) 本地高可用这个方案为了保持业务的连续性,从两个层面来考虑: ①一个是从主 ...