You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Jar包的resources中获取文件或目录列表?

从Jar包的resources中获取文件或目录列表

下面两种常见方法可以实现需求,同时兼容开发环境(本地文件系统)和Jar包运行环境:

方法一:通过ClassLoader解析Jar文件

Jar包本质是压缩文件,无法用普通File类直接访问,需要借助JarFile遍历条目:

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

public class ResourceScanner {
    public static void scanResources(String targetPath) throws IOException {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        URL resourceUrl = classLoader.getResource(targetPath);
        
        if (resourceUrl == null) {
            System.out.println("目标路径不存在:" + targetPath);
            return;
        }

        String protocol = resourceUrl.getProtocol();
        if ("jar".equals(protocol)) {
            JarURLConnection jarConn = (JarURLConnection) resourceUrl.openConnection();
            JarFile jarFile = jarConn.getJarFile();
            Enumeration<JarEntry> entries = jarFile.entries();

            while (entries.hasMoreElements()) {
                JarEntry entry = entries.nextElement();
                String entryName = entry.getName();
                
                // 筛选目标路径下的资源,排除路径本身
                if (entryName.startsWith(targetPath) && !entryName.equals(targetPath)) {
                    if (entry.isDirectory()) {
                        // 提取目录名,去除前缀和末尾斜杠
                        String dirName = entryName.substring(targetPath.length()).replaceFirst("^/", "").replaceAll("/$", "");
                        if (!dirName.isEmpty()) {
                            System.out.println("目录:" + dirName);
                        }
                    } else {
                        // 提取文件名
                        String fileName = entryName.substring(entryName.lastIndexOf("/") + 1);
                        System.out.println("文件:" + fileName);
                    }
                }
            }
            jarFile.close();
        } else if ("file".equals(protocol)) {
            // 开发环境直接遍历本地目录
            java.io.File dir = new java.io.File(resourceUrl.getFile());
            if (dir.isDirectory()) {
                String[] names = dir.list();
                if (names != null) {
                    for (String name : names) {
                        java.io.File item = new java.io.File(dir, name);
                        System.out.println(item.isDirectory() ? "目录:" + name : "文件:" + name);
                    }
                }
            }
        }
    }

    public static void main(String[] args) throws IOException {
        // 示例:获取resources下insights目录的内容
        scanResources("insights");
        // 示例:获取resources下存放json文件的目录内容
        scanResources("json_data");
    }
}

方法二:用NIO FileSystem简化操作(Java 7+)

Java 7引入的FileSystem API可以把Jar包当作独立文件系统处理,代码更简洁:

import java.io.IOException;
import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;

public class NioResourceScanner {
    public static void scanResources(String targetPath) throws IOException {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        URL resourceUrl = classLoader.getResource(targetPath);
        
        if (resourceUrl == null) {
            System.out.println("目标路径不存在:" + targetPath);
            return;
        }

        String protocol = resourceUrl.getProtocol();
        if ("jar".equals(protocol)) {
            // 解析Jar文件路径,格式为jar:file:/xxx.jar!/path
            String jarPath = resourceUrl.getPath().substring(5, resourceUrl.getPath().indexOf("!"));
            URI jarUri = URI.create("jar:file:" + jarPath);

            try (FileSystem jarFs = FileSystems.newFileSystem(jarUri, Collections.emptyMap())) {
                Path path = jarFs.getPath(targetPath);
                if (Files.exists(path)) {
                    Files.list(path).forEach(item -> {
                        String name = item.getFileName().toString();
                        System.out.println(Files.isDirectory(item) ? "目录:" + name : "文件:" + name);
                    });
                }
            }
        } else if ("file".equals(protocol)) {
            // 开发环境遍历本地目录
            Path path = Paths.get(resourceUrl.getFile());
            if (Files.isDirectory(path)) {
                Files.list(path).forEach(item -> {
                    String name = item.getFileName().toString();
                    System.out.println(Files.isDirectory(item) ? "目录:" + name : "文件:" + name);
                });
            }
        }
    }

    public static void main(String[] args) throws IOException {
        scanResources("openapi");
        scanResources("daily_json");
    }
}

关键注意点

  • 打包时确保resources目录下的内容被正确包含,Maven/Gradle默认会处理,但自定义配置时要检查。
  • 路径用斜杠/分隔,不要加末尾斜杠(比如用"insights"而非"insights/"),避免筛选逻辑出错。
  • Jar包内的资源是只读的,只能读取不能修改。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 17:25:14