簡單的文件操做工具類(File)

1.解決問題

經過形如:com.xxx.yyy.zzz形式的包名,加載包下全部的類java

2.代碼:

package com.chuyutech.rssp.openservice.service.data;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * @description: 簡單的文件操做類,包含一些文件的基本操做
 * 
 * @author cwh
 *
 */
public class FileOpreation {

	/**
	 * 根據包名訪問磁盤文件
	 * 
	 * @param packageName:形如com.xxx.yyy.zzz以點號分割
	 */
	public static Set<Class<?>> getClazz(String packageName) {
		// 是否遞歸
		boolean isRecursion = true;
		// 定義變量,保存class文件
		Set<Class<?>> clazz = new LinkedHashSet<Class<?>>();
		char dot = '.';
		char sprit = '/';
		try {
			// 根據當前線程獲取ContextClassLoader類加載器 需注意:分隔符的轉換
			// getResources方法定義的資源是 '/' 分隔符

			Enumeration<URL> resources = Thread.currentThread().getContextClassLoader()
					.getResources(packageName.replace(dot, sprit));
			// 遍歷枚舉
			while (resources.hasMoreElements()) {
				URL url = resources.nextElement();
// url:file:/E:/03.WorkSpaceToNew/soldier-openservice/target/classes/com/chuyutech/rssp/openservice/common/db/dao
				System.out.println("url:" + url.toString());
				// 獲取協議名稱
				String protocol = url.getProtocol();
				// 若是爲文件類型 接下來就是File類的操做
				if (protocol.equals("file")) {
					//					使用特定的編碼方案解碼url
					String packagePath = URLDecoder.decode(url.getFile(), "UTF-8");
//					調用方法遞歸獲取文件
					getClazzFromPath(packageName, packagePath, isRecursion, clazz);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return clazz;
	}

	/**
	 * 獲取文件中class文件
	 * 
	 * @param packageName:包名;
	 *            packagePath:文件路徑;isRecursion:是否遞歸
	 */
	public static void getClazzFromPath(String packageName, String packagePath, boolean isRecursion,
			Set<Class<?>> clazz) {
		char dot = '.';
		// 根據路徑名獲取File文件對象
		File file = new File(packagePath);

		if (!file.exists() || !file.isDirectory()) {
			return;
		}
		// 以File數組的形式列出全部的文件
		File[] files = file.listFiles(new FileFilter() {
			// 匿名內部類重寫FIleFilter
			@Override
			public boolean accept(File pathName) {
	// 自定義過濾規則 若是能夠循環(包含子目錄) 或者是以.class結尾的文件(編譯好的java類文件)
				return ((isRecursion && pathName.isDirectory()) || pathName.getName().endsWith(".class"));
			}
		});
		// 遍歷files
		for (File destFile : files) {
			// 若是是目錄 則繼續掃描
			if (destFile.isDirectory()) {
				getClazzFromPath(packageName + dot + destFile.getName(), destFile.getAbsolutePath(), isRecursion,
						clazz);
			} else {
				// 若是是編譯後java類文件 去掉後面的.class 只留下類名
				String fileName = destFile.getName().substring(0, destFile.getName().lastIndexOf(dot));
				// 添加到集合中去 經過完整包名+"."+文件名 加載class
				try {
					// Class<?> forName = Class.forName(packageName + dot +
					// className); 此方法在會初始化所加載類的static靜態代碼塊
					Class<?> loadClass = Thread.currentThread().getContextClassLoader()
							.loadClass(packageName + dot + fileName);
					clazz.add(loadClass);
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
			}

		}
	}

	public static void main(String[] args) {
		String packageName = "com.chuyutech.rssp.openservice.common.db.dao";
		Set<Class<?>> clazz = getClazz(packageName);
		System.out.println(clazz.size());
		for (Class<?> class1 : clazz) {
			System.out.println(class1.getName());
		}
	}

}

3.總結:

        3.1:實現的大體邏輯:數組

            根據當前線程獲取ContextClassLoader類加載器 ,經過類加載器的getResources(String name)方法獲取包名所對應的URL.ide

            經過URL獲取絕對路徑,使用File類的 java.io.listFiles(FileFilter filter)列出全部的文件或目錄編碼

            對上一步獲取的文件或目錄遞歸調用,最後經過Thread.currentThread().getContextClassLoader()
                            .loadClass(className)獲取到Class對象保存到set集合中.url

           3.2:注意:分隔符的轉換:getResources方法定義的資源是 '/' 分隔符spa


4.結果打印:

---------------------over-----------------------.net

相關文章
相關標籤/搜索