package com.shdl.htscada.utils; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.JarURLConnection; import java.net.URL; import java.net.URLClassLoader; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; /** * 遍歷指定包名下所有的類(支持jar) * @author ht-meeting * @date 2017年7月7日 */ public class ClassFilesUtils { public static void main(String[] args) throws Exception { String packageName = "com.shdl.htscada.i18n"; Set<String> classNames = getClassName(packageName, false, ".properties"); if (classNames != null) { for (String className : classNames) { System.out.println(className); } } } /** * 獲取某包下所有類 * @param packageName 包名 * @param isRecursion 是否遍歷子包 * @param suffixstr 後綴名 * @return 類的完整名稱 */ public static Set<String> getClassName(String packageName, boolean isRecursion ,String suffixstr) { Set<String> classNames = null; ClassLoader loader = Thread.currentThread().getContextClassLoader(); String packagePath = packageName.replace(".", "/"); URL url = loader.getResource(packagePath); if (url != null) { String protocol = url.getProtocol(); if (protocol.equals("file")) { classNames = getClassNameFromDir(url.getPath(), packageName, isRecursion, suffixstr); } else if (protocol.equals("jar")) { JarFile jarFile = null; try{ jarFile = ((JarURLConnection) url.openConnection()).getJarFile(); } catch(Exception e){ e.printStackTrace(); } if(jarFile != null){ getClassNameFromJar(jarFile.entries(), packageName, isRecursion); } } } else { /*從所有的jar包中查找包名*/ classNames = getClassNameFromJars(((URLClassLoader)loader).getURLs(), packageName, isRecursion); } return classNames; } /** * 從項目文件獲取某包下所有類 * @param filePath 文件路徑 * @param className 類名集合 * @param isRecursion 是否遍歷子包 * @param suffixstr 後綴名 * @return 類的完整名稱 */ private static Set<String> getClassNameFromDir(String filePath, String packageName, boolean isRecursion, String suffixstr) { Set<String> className = new HashSet<String>(); try { filePath = java.net.URLDecoder.decode(new String(filePath.getBytes("ISO-8859-1"), "UTF-8"), "UTF-8"); File file = new File(filePath); File[] files = file.listFiles(); for (File childFile : files) { if (childFile.isDirectory()) { if (isRecursion) { className.addAll(getClassNameFromDir(childFile.getPath(), packageName+"."+childFile.getName(), isRecursion, suffixstr)); } } else { String fileName = childFile.getName(); if (fileName.endsWith(suffixstr) && !fileName.contains("$")) { //className.add(fileName); className.add(packageName+ "." + fileName); } } } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return className; } /** * @param jarEntries * @param packageName * @param isRecursion * @return */ private static Set<String> getClassNameFromJar(Enumeration<JarEntry> jarEntries, String packageName, boolean isRecursion){ Set<String> classNames = new HashSet<String>(); while (jarEntries.hasMoreElements()) { JarEntry jarEntry = jarEntries.nextElement(); if(!jarEntry.isDirectory()){ /* * 這裏是爲了方便,先把"/" 轉成 "." 再判斷 ".class" 的做法可能會有bug * (FIXME: 先把"/" 轉成 "." 再判斷 ".class" 的做法可能會有bug) */ String entryName = jarEntry.getName().replace("/", "."); if (entryName.endsWith(".class") && !entryName.contains("$") && entryName.startsWith(packageName)) { entryName = entryName.replace(".class", ""); if(isRecursion){ classNames.add(entryName); } else if(!entryName.replace(packageName+".", "").contains(".")){ classNames.add(entryName); } } } } return classNames; } /** * 從所有jar中搜索該包,並獲取該包下所有類 * @param urls URL集合 * @param packageName 包路徑 * @param isRecursion 是否遍歷子包 * @return 類的完整名稱 */ private static Set<String> getClassNameFromJars(URL[] urls, String packageName, boolean isRecursion) { Set<String> classNames = new HashSet<String>(); for (int i = 0; i < urls.length; i++) { String classPath = urls[i].getPath(); //不必搜索classes文件夾 if (classPath.endsWith("classes/")) {continue;} JarFile jarFile = null; try { jarFile = new JarFile(classPath.substring(classPath.indexOf("/"))); } catch (IOException e) { e.printStackTrace(); } if (jarFile != null) { classNames.addAll(getClassNameFromJar(jarFile.entries(), packageName, isRecursion)); } } return classNames; } }
java 遍歷指定包名下所有的類(支持jar)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.