获取包以及jar 包下的类

首先,Java中的getResourceAsStream获取项目下的指定资源有以下几种: 

一:获取src下的指定资源

1 通过Class.getResource 来获取。  path 不以’/'开头时默认是从此类所在的包下取资源,以’/'开头则是从ClassPath根下(即'/'代表src)获取。其只是通过path构造一个绝对路径,最终还是由ClassLoader获取资源

 //必须要从根节点进行获取,即以/ 开头       
 TempMain.class.getResource("/application.yml");

2 Class.getResourceAsStream 与Class.getResource 一样,只是将获取到的URL 进行了流的处理 

TempMain.class.getResourceAsStream("/application.yml");

 

3 Class.getClassLoader.getResourceAsStream(String path) :默认则是从ClassPath根下获取,path不能以’/'开头,最终是由ClassLoader获取资源。

TempMain.class.getClassLoader().getResourceAsStream("application.yml");

4 备注:

如果当前项目里引用里其他的jar 包,并且在相同的路径下存在着相同的文件,那么也会读取到,spring 的starter 就是利用改机制来发现配置类,从而实现自动装配的

二:获取web项目下的指定资源

    1)、 ServletContext. getResourceAsStream(String path):默认从WebAPP根目录(即:要发布在服务器下的项目的根目录(与src同级的web文件夹下))下取资源,path是否以’/'开头无所谓;

   A)、在web项目的根目录下有myfile.xml文件,则应该使用:

getServleContext().getResourceAsStream("myfile.xml");

 

2)、Jsp下的application内置对象就是上面的ServletContext的一种实现

三 获取指定包下的所有class类

需要先将包名转化为路径名,比如讲org.apache 转换为 org/apache ,然后通过循环遍历找到该文件下有哪些类,然后在将路径名转化为类名,通过反射即可拿到。 

或者通过第一步获取到了资源文件 , 然后通过解析资源文件, 获取到对应的ClassName ,然后通过反射来实现 。 (可以使用Spring 中的 ClassReader )

四 获取jar包里的class文件

先通过第一种方法获取到对应的jar文件,然后通过 

1.通过jarFile
JarFile jarFile = new JarFile(file); 
2 通过 jarInputStream ,Demo里有

获取到jarFile,接着通过第三部即可

五 demo

public class ClassUtil {

    private static final byte[] JAR_MAGIC = {'P', 'K', 3, 4};


    public static void main(String[] args) throws IOException {
        ClassUtil classUtil = new ClassUtil();
        List<Class> classes = classUtil.listClass("com.google");
        System.out.println(classes);
    }


    public List<Class> listClass(String packageName) throws IOException {
        List<String> list = listResource(packageName);
        List<Class> result = new ArrayList<>();
        for (String name : list) {

            name = name.substring(0, name.lastIndexOf(".")).replace("/", ".");
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            try {
                Class<?> aClass = classLoader.loadClass(name);
                result.add(aClass);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    public List<String> listResource(String packageName) throws IOException {
        String path = packageName.replace(".", "/");
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        URL url = classLoader.getResource(path);
        URL jarUrl = findJarForResource(url);

        // 如果是jar包的话
        if (jarUrl != null) {
            return listResources(new JarInputStream(jarUrl.openStream()), path);
        }

        InputStream is = url.openStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        List<String> resources = Lists.newArrayList();
        String line;
        while ((line = reader.readLine()) != null) {
            //如果是类的话
            if (line.indexOf(".class") > 0) {
                resources.add(path + "/" +line);
            // 是目录的话
            }else{
                List<String> children = listResource(path + "/" + line);
                if(children!=null && children.size()>0){
                    resources.addAll(children);
                }
            }
        }
        reader.close(); 
        return resources;
    }

    private URL findJarForResource(URL url) throws IOException {
        String jarUrl = url.getPath();
        int index = jarUrl.indexOf(".jar");
        if (index < 0) {
            return null;
        }

        jarUrl = jarUrl.substring(0, index + 4);
        URL testUrl = new URL(jarUrl);
        if (isJar(testUrl)) {
            return testUrl;
        }
        return null;
    }
    // 通过文件的魔数来判断是否是jar 文件
    private boolean isJar(URL testUrl) throws IOException {
        InputStream inputStream = testUrl.openStream();
        byte[] buffer = new byte[JAR_MAGIC.length];
        inputStream.read(buffer, 0, JAR_MAGIC.length);
        if (Arrays.equals(JAR_MAGIC, buffer)) {
            return true;
        }
        inputStream.close();
        return false;
    }

    // 通过jar 来获取resourced
    protected List<String> listResources(JarInputStream jar, String path) throws IOException {
        //为path 在开头和末尾添加 /
        if (!path.startsWith("/")) {
            path = "/" + path;
        }
        if (!path.endsWith("/")) {
            path = path + "/";
        }

        List<String> resources = new ArrayList<>();
        for (JarEntry entry; (entry = jar.getNextJarEntry()) != null; ) {
            if (!entry.isDirectory()) {
                StringBuilder name = new StringBuilder(entry.getName());
                // 进行文件名的统一
                if (name.charAt(0) != '/') {
                    name.insert(0, '/');
                }

                if (name.indexOf(path) == 0) {
                    // 去掉开头的斜杠
                    resources.add(name.substring(1));
                }
            }
        }
        return resources;
    }
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用Java中的反射机制来获取Jar包中指定路径下的。以下是一个示例代码: ```java 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 JarUtils { public static List<Class<?>> getClassesFromJar(String jarFilePath, String packagePath) throws IOException, ClassNotFoundException { List<Class<?>> classList = new ArrayList<>(); JarFile jarFile = new JarFile(jarFilePath); Enumeration<JarEntry> entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry jarEntry = entries.nextElement(); String name = jarEntry.getName().replace("/", "."); if (name.startsWith(packagePath) && name.endsWith(".class")) { String className = name.substring(0, name.length() - 6); Class<?> clazz = Class.forName(className); classList.add(clazz); } } return classList; } public static void main(String[] args) throws IOException, ClassNotFoundException { String jarFilePath = "/path/to/your/jar/file.jar"; String packagePath = "com.example.package"; List<Class<?>> classList = getClassesFromJar(jarFilePath, packagePath); for (Class<?> clazz : classList) { System.out.println(clazz.getName()); } } } ``` 在上面的示例代码中,`getClassesFromJar` 方法接收两个参数:`jarFilePath` 表示 Jar 文件的路径,`packagePath` 表示要查找的路径。该方法会遍历 Jar 中的所有,找到指定路径下的,并将其添加到 `classList` 列表中返回。你可以在 `main` 方法中调用该方法,并打印出每个找到的的完整名。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值