You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

获取资源包内所有文件名,适配Jar与非Jar运行场景

兼容Jar包与开发环境的资源目录文件遍历方案

嘿,我之前做Java桌面应用的时候也踩过这个资源读取的坑,刚好能给你一个靠谱的解决方案。核心思路是区分当前运行环境是文件系统(开发时)还是Jar包内,然后分别处理文件遍历逻辑:

核心实现步骤

  1. 获取目标资源目录的URL,通过Class.getResource()方法,注意路径要以/开头,对应项目的resources根目录
  2. 根据URL的协议(filejar)判断运行环境
  3. 针对不同环境实现文件遍历:
    • 开发环境(file协议):直接用File类遍历目录
    • Jar包环境(jar协议):通过JarURLConnection获取Jar文件,遍历其中的条目筛选目标文件

完整代码示例

import java.io.File;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class PresetLoader {
    private static final String PRESET_DIR_PATH = "/resources/presets/";
    private static final String FILE_EXTENSION = ".txt";

    public List<String> getPresetFileNames() throws IOException {
        List<String> presetFiles = new ArrayList<>();
        URL dirUrl = getClass().getResource(PRESET_DIR_PATH);

        if (dirUrl == null) {
            throw new IOException("预设目录不存在: " + PRESET_DIR_PATH);
        }

        switch (dirUrl.getProtocol()) {
            case "file":
                // 开发环境:直接遍历文件系统目录
                File dir = new File(dirUrl.getFile());
                if (dir.isDirectory()) {
                    File[] files = dir.listFiles((d, name) -> name.endsWith(FILE_EXTENSION));
                    if (files != null) {
                        for (File file : files) {
                            presetFiles.add(file.getName());
                        }
                    }
                }
                break;

            case "jar":
                // Jar包环境:解析Jar文件遍历条目
                JarURLConnection jarConn = (JarURLConnection) dirUrl.openConnection();
                try (JarFile jarFile = jarConn.getJarFile()) {
                    Enumeration<JarEntry> entries = jarFile.entries();
                    String presetDir = PRESET_DIR_PATH.substring(1); // 去掉开头的/,匹配Jar内路径
                    while (entries.hasMoreElements()) {
                        JarEntry entry = entries.nextElement();
                        String entryName = entry.getName();
                        // 筛选出预设目录下的txt文件,且不是目录本身
                        if (entryName.startsWith(presetDir) && entryName.endsWith(FILE_EXTENSION) && !entry.isDirectory()) {
                            // 只提取文件名,去掉路径前缀
                            String fileName = entryName.substring(presetDir.length());
                            presetFiles.add(fileName);
                        }
                    }
                }
                break;

            default:
                throw new IOException("不支持的资源协议: " + dirUrl.getProtocol());
        }

        return presetFiles;
    }
}

关键注意事项

  • 路径正确性PRESET_DIR_PATH必须以/开头,确保指向resources根目录下的presets文件夹,不管是开发环境还是Jar包内都能正确定位
  • 打包配置:如果用Maven/Gradle构建,要确保src/main/resources/presets目录被正确打包进Jar。比如Maven的pom.xml里默认会包含resources目录,不用额外配置;如果是自定义结构,要在build的resources节点里添加包含规则
  • 资源关闭:JarFile要放在try-with-resources块里自动关闭,避免资源泄漏
  • 异常处理:实际使用时可以根据业务需求调整异常抛出逻辑,比如返回空列表而不是抛出异常

这样不管你是在IDE里运行开发,还是打包成Jar后运行,都能正确获取到所有预设关卡的txt文件名啦!

内容的提问来源于stack exchange,提问作者Scorix

火山引擎 最新活动