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; } } /** 获取资源

* @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); } // 否则回退到 classpath(JAR、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 } }