Java:IO/NIO篇,利用IO遍历目录示范(示范:从指定目录的JAR包中查找指定类)
1. 问题
因为项目有时需要查找一个类属于哪个JAR包,知道类名,知道大概路径,但不知道具体在哪个JAR包中,所以写了这样的一个小程序,来实现查找JAR包的作用。
2. 解决
package com.clzhang.sample.io; import java.util.*; import java.io.*; import java.util.jar.*; /** * 这是一个从指定目录(包括子目录)的各种JAR/ZIP包中查找指定类文件的程序。 * 指定目录形如:C:\JavaApp\android-sdk-windows\platforms\android-17 * 指定目录也可以直接是一个JAR/ZIP包,比如: * C:\JavaApp\android-sdk-windows\platforms\android-17\data\layoutlib.jar * * 指定类形如:libcore.net.UriCodec * * 示范:可以从C:\JavaApp\android-sdk-windows\platforms\android-17\data目录中的layoutlib.jar包中找到:libcore.net.UriCodec类 * 也可以从C:\JavaApp\android-sdk-windows\platforms目录的子目录中找到:libcore.net.UriCodec类,需要时间稍长些而已。 * * @author acer * */ public class FindClassInJar { // 查找目录起始位置 private String m_libDir; // 需要查找的类名 private String m_classname; // 总计查找到的个数 int m_count = 0; // 构造器 libDir 查找目录起始位置 classname 需要查找的类名 public FindClassInJar(String libDir, String classname) { m_libDir = libDir; m_classname = classname; } // 文件过滤器,仅目录、JAR/ZIP文件格式通过 class JarZipFileFilter implements FileFilter { public boolean accept(File file) { if (file.isDirectory()) return true; String name = file.getName().toLowerCase(); if (name.endsWith(".jar") || name.endsWith(".zip")) { return true; } else { return false; } } } // 开始处理,与真实处理的分开了,主要原因是调用格式可能是从目录开始查找,也可能是从文件开始查找, // 所以让外界直接调用checkDirectory()方法似乎有些不太合适。 public void process() throws Exception { checkDirectory(m_libDir); } // 检查目录/文件,命名似乎有些不太合适,先这样吧。 private void checkDirectory(String libDir) throws Exception { File file = new File(libDir); if (file.isFile()) { // 允许不是目录,直接是一个文件(JAR、ZIP等) if (checkFile(file)) { m_count++; System.out.println(file.getName() + "包中包含了类:" + m_classname); } } else { File[] files = file.listFiles(new JarZipFileFilter()); for (int i = 0; i < files.length; i++) { File f = files[i]; if (f.isDirectory()) { checkDirectory(f.getAbsolutePath()); } else { System.out.println("正在检查:" + f.getAbsolutePath()); if (checkFile(f)) { m_count++; System.out.println(f.getName() + "包中包含了类:" + m_classname); } } } } } // 从JAR/ZIP包中查找类文件 private boolean checkFile(File f) { boolean result = false; try { JarFile jarFile = new JarFile(f); Enumeration<JarEntry> enu = jarFile.entries(); while (enu.hasMoreElements()) { JarEntry entry = enu.nextElement(); String name = entry.getName(); if (entry.isDirectory()) { continue; } if (name.equals(m_classname)) { result = true; break; } } jarFile.close(); } catch (Exception ex) { ex.printStackTrace(); } return result; } // 取得总计查找到的目标类数量 private int getCount() { return m_count; } public static void main(String args[]) throws Exception { String libDir = "D:\\Resources"; // String libDir = "C:\\JavaApp\\android-sdk-windows\\platforms\\android-17\\data\\layoutlib.jar"; String classname = "org.slf4j.impl.StaticLoggerBinder"; classname = classname.replaceAll("\\.", "/") + ".class"; System.out.println("开始在路径:" + libDir + "中查找:" + classname + "类......"); FindClassInJar ins = new FindClassInJar(libDir, classname); ins.checkDirectory(libDir); System.out.println("总计找到:" + ins.getCount() + "个符合要求的类!"); } }