net.lulihu.ObjectKit.ResourcesLoadKit Maven / Gradle / Ivy
package net.lulihu.ObjectKit;
import lombok.extern.slf4j.Slf4j;
import sun.net.www.protocol.file.FileURLConnection;
import java.io.*;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
/**
* jar 资源加载工具
*/
@Slf4j
public class ResourcesLoadKit {
private static final Class clazz = ResourcesLoadKit.class;
/**
* 从jar包下加载文件夹资源
*
* @param folderPath 文件夹
* @param targetFolderPath 目标文件夹
* @throws IOException 文件拷贝错误时抛出异常
*/
public static void loadResourcesFromJarByFolder(String folderPath, String targetFolderPath) throws IOException {
URL url = clazz.getResource(folderPath);
URLConnection urlConnection = url.openConnection();
if (urlConnection instanceof FileURLConnection) {
copyFileResources(url, folderPath, targetFolderPath);
} else if (urlConnection instanceof JarURLConnection) {
copyJarResources((JarURLConnection) urlConnection, targetFolderPath);
}
}
/**
* 当前运行环境资源文件是在文件里面的
*/
private static void copyFileResources(URL url, String folderPath, String targetFolderPath) throws IOException {
File root = new File(url.getPath());
if (root.isDirectory()) {
File[] files = root.listFiles();
if (CollectionKit.isEmpty(files)) return;
for (File file : files) {
if (file.isDirectory()) {
loadResourcesFromJarByFolder(folderPath + "/" + file.getName(), targetFolderPath);
} else {
loadResourcesFromJar(folderPath + "/" + file.getName(), targetFolderPath);
}
}
}
}
/**
* 当前运行环境资源文件是在jar里面的
*/
private static void copyJarResources(JarURLConnection jarURLConnection, String targetFolderPath) throws IOException {
try (JarFile jarFile = jarURLConnection.getJarFile()) {
Enumeration entrys = jarFile.entries();
while (entrys.hasMoreElements()) {
JarEntry entry = entrys.nextElement();
if (entry.getName().startsWith(jarURLConnection.getEntryName()) && !entry.getName().endsWith("/")) {
loadResourcesFromJar("/" + entry.getName(), targetFolderPath);
}
}
}
}
/**
* 在jar中加载文件资源
*
* @param path 资源文件下的相对文件路径
* @param targetFolderPath 目标文件夹
* @throws IOException 文件拷贝错误时抛出异常
*/
private static void loadResourcesFromJar(String path, String targetFolderPath) throws IOException {
if (!path.startsWith("/")) {
throw new IllegalArgumentException("路径必须是绝对的(以'/'开头)。");
}
if (path.endsWith("/")) {
throw new IllegalArgumentException("路径必须是绝对的(不以'/'结尾)。");
}
int index = path.lastIndexOf('/');
String filename = path.substring(index + 1);
String folderPath = targetFolderPath + path.substring(0, index + 1);
// 如果该文件夹尚不存在,则将创建该文件夹。如果该文件夹已存在,则将被忽略
File dir = new File(folderPath);
if (!dir.exists()) dir.mkdirs();
// 如果该文件尚不存在,则将创建该文件。如果文件已存在,则将被忽略
filename = folderPath + filename;
File file = new File(filename);
if (!file.exists() && !file.createNewFile()) {
log.error("创建文件失败,文件名:{}", filename);
return;
}
// 准备缓冲区以进行数据复制
byte[] buffer = new byte[1024];
int readBytes;
try (InputStream is = loadResourcesInputStream(path)) {
if (is == null) throw new FileNotFoundException("文件 " + path + " 在JAR里面找不到");
try (OutputStream os = new FileOutputStream(file)) {
while ((readBytes = is.read(buffer)) != -1) {
os.write(buffer, 0, readBytes);
}
}
}
}
/**
* 加载资源输入流
*
* @param path 资源地址
* @return {@linkplain InputStream}
* @throws IOException 文件异常
*/
public static InputStream loadResourcesInputStream(String path) throws IOException {
URL url = clazz.getResource(path);
URLConnection urlConnection = url.openConnection();
return urlConnection.getInputStream();
}
}