Files
emo-grab/src/main/java/quant/rich/emoney/util/SmartResourceResolver.java

112 lines
4.1 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package quant.rich.emoney.util;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class SmartResourceResolver {
private static RunningFrom runningFrom;
static {
if (isRunningFromJar()) {
runningFrom = RunningFrom.JAR;
}
else if (isRunningFromWar()) {
runningFrom = RunningFrom.WAR;
}
else {
runningFrom = RunningFrom.IDE;
}
}
/**
获取资源
<p>
<ul>
<li>JAR
<ul>
<li>优先以 jar 文件所在目录为基准,寻找相对路径外部文件</li>
<li>当外部文件不存在时,读取 classpath即 jar 内部资源文件</li>
</ul>
</li>
<li>WAR 只获取 classpath 文件,即 /WEB-INF/classes/ 下文件</li>
<li>IDE 只获取源文件,即 src/main/resources/ 下文件</li>
</ul></p>
* @param relativePath 相对路径
* @param writable 是否一定可写
* @return
*/
public static InputStream loadResource(String relativePath) {
try {
Path externalPath = resolveExternalPath(relativePath);
if (externalPath != null && Files.exists(externalPath)) {
log.debug("从外部文件系统加载资源: {}", externalPath);
return Files.newInputStream(externalPath);
}
// 否则回退到 classpathJAR、WAR、IDE
InputStream in = SmartResourceResolver.class.getClassLoader().getResourceAsStream(relativePath);
if (in != null) {
log.debug("从 classpath 内部加载资源: {}", relativePath);
return in;
}
throw new FileNotFoundException("无法找到资源: " + relativePath);
} catch (Exception e) {
throw new RuntimeException("读取资源失败: " + relativePath, e);
}
}
public static void saveText(String relativePath, String content) throws IOException {
Path outputPath = resolveExternalPath(relativePath);
Files.createDirectories(outputPath.getParent()); // 确保目录存在
Files.writeString(outputPath, content, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
log.debug("写入外部资源文件成功: {}", outputPath);
}
private static Path resolveExternalPath(String relativePath) {
try {
Path basePath;
if (runningFrom == RunningFrom.JAR) {
basePath = Paths.get(SmartResourceResolver.class.getProtectionDomain()
.getCodeSource().getLocation().toURI()).getParent();
return basePath.resolve(relativePath).normalize();
} else if (runningFrom == RunningFrom.WAR) {
basePath = Paths.get(SmartResourceResolver.class.getProtectionDomain()
.getCodeSource().getLocation().toURI()); // e.g., WEB-INF/classes/
return basePath.resolve(relativePath).normalize();
} else {
// IDE 环境:返回 src/main/resources 下真实文件
return Paths.get("src/main/resources", relativePath).normalize();
}
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
private static boolean isRunningFromJar() {
String path = SmartResourceResolver.class.getResource(
SmartResourceResolver.class.getSimpleName() + ".class").toString();
return path.startsWith("jar:");
}
private static boolean isRunningFromWar() {
String path = SmartResourceResolver.class.getResource(
SmartResourceResolver.class.getSimpleName() + ".class").toString();
return path.contains("/WEB-INF/classes/");
}
private static enum RunningFrom {
JAR,
WAR,
IDE
}
}