你知道怎么从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命令执行.每次上传前都要通过解压缩软件修改或者替换里面的配置文件, ...
随机推荐
- Java基础系列(35)- 数组声明创建
数组声明创建 首先必须声明数组变量,才能在程序中使用数组.下面是声明数组变量的语法: dataType[] arrayRefVar; //首选的方法 或 dataType arrayRefVar[]; ...
- Linux系列(32) - rpm命令管理之RPM查询(4)
RPM包默认安装位置 RPM包默认安装路径 /etc/ 配置文件安装目录 /usr/bin/ 可执行的命令安装目录 /usr/lib/ 程序所使用的函数库保存位置 /usr/share/doc/ 基本 ...
- OC源码剖析对象的本质
1. 类的底层实现 先写一个 Person 类: @interface Person : NSObject @property (nonatomic, copy) NSString *p_name; ...
- java 小算法
//鸡兔同笼 20个头 58腿 for(int a=0;a<=20;a++) { int b = 20-a; if((2*b+4*a)==58) { System.out.println(a+& ...
- [转载]提升SQLite数据插入效率低、速度慢的方法
转载地址:http://blog.csdn.net/chenguanzhou123/article/details/9376537#,如果有侵犯原创,请留言告知,本人会及时删除. 前言 SQLite数 ...
- 定要过python二级选择题二套
1. 2. 3. 4. 5. 6. 7. 8. 非主属性???? 9. 10.. 11.` 调用只是调用,但是没有返回值,,应为里面没有输出 12. 13. 14. 15. 16. 18. 19.
- 定要过python二级 真题 第四套
第一模块 基本操作 1.print(" { } " . format(s)) 记住 " { }" ...
- P1912-[NOI2009]诗人小G【四边形不等式,单调队列】
正题 题目链接:https://www.luogu.com.cn/problem/P1912 题目大意 给出\(n\)个字符串,把这些字符串依次用空格(算一个长度)连接分成若干段,若一段长度为\(x\ ...
- "错误: 找不到或无法加载主类"解决办法
前言:记上次一个找了个把小时的问题(很烦这些配置) 原因: 从svn下checkOut的项目 在application的配置的输出class路径为main,而class文件路径是在项目名的根路径下,所 ...
- 【Ubuntu】VirtualBox 您没有查看“sf_VirtualDisk”的内容所需的权限
但是现在发现无法去访问,没有权限: 即使是: crifan@crifan-Ubuntu:~$ sudo chown -R crifan /media/sf_win7_to_ubuntu/ cr ...