欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java 读取jar包中的资源文件或文件夹(解决错误: java.lang.IllegalArgumentException: URI is not hierarchical)

程序员文章站 2022-04-28 11:24:37
...

最近解决了个问题,springboot启动是,需要将resources资源文件夹下的模板子文件夹中的所有文件加载解析并初始化。原本可以使用Thread.currentThread().getContextClassLoader().getResource(TEMPLATE_PATH).toURI() (或者Main.class.getClassLoader().getResoruceAsStream())但是为了避免在项目中加载不到本项目中静态资源文件的BUG发生,调用静态资源的classLoader最好用Thread.currentThread().getContextClassLoader()方法来获取,因为一般同一个项目中java代码和其静态资源文件都是同一个classLoader来加载的,以此确保通过此classLoader也能加载到本项目中的资源文件。将文件一一加载,但是模板子文件夹中的文件非常多,不可能一个个列文件名。所以最初我的写法是:


private static final String TEMPLATE_PATH = "init/defaultTemplate";

File file = new File(Thread.currentThread().getContextClassLoader().getResource(TEMPLATE_PATH).toURI());
			File[] array = file.listFiles();
			for (File tempFile : array) {
            
				String fileName = tempFile.getName();
			}

 

Java 读取jar包中的资源文件或文件夹(解决错误: java.lang.IllegalArgumentException: URI is not hierarchical)

这种方式在idea中执行是没有问题的,但打成jar在linux或其他环境执行就报错: java.lang.IllegalArgumentException: URI is not hierarchical

分析了下原因:jar包中的文件不能通过这种方式读取,因为目录是不透明的,

找到解决方案:在jar中循环读取子文件夹及目录;根据要读取的目录在去过滤,即可循环找出对应的文件或文件夹资源

//liunx 解析对应的jar,循环文件夹,找到TEMPLATE_PATH文件所在位置
				URL url= Thread.currentThread().getContextClassLoader().getResource(TEMPLATE_PATH);
//截取jar路径			
	String jarPath = url.toString().substring(0, url.toString().indexOf(TEMPLATE_PATH));
				URL jarURL = new URL(jarPath);
				JarURLConnection jarCon = (JarURLConnection) jarURL.openConnection();
				JarFile jarFile = jarCon.getJarFile();
				Enumeration<JarEntry> jarEntrys = jarFile.entries();
//循环jar中所有文件夹
				while (jarEntrys.hasMoreElements()) {
					JarEntry entry = jarEntrys.nextElement();
					String className = entry.getName();
//判断已路径开头的文件夹及子文件
					if (className.startsWith(TEMPLATE_PATH) && !entry.isDirectory()) {
						String fileName = className.replace(TEMPLATE_PATH+"/","");
						InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(className);
						File file = new File(String.valueOf(inputStream));

					}
				}