zoukankan      html  css  js  c++  java
  • java查找反复类/jar包/普通文件

    开发web应用时,有时更新了类却没有生效,事实上是由于jboss/tomcat中其它公布包下有同名类(包含全路径都同样)。

    于是萌发了做个程序来检查指定文件夹是否存在反复类(通过asm从类文件里取类的全路径),扩展开来,还支持查找反复的文件(按文件md5进行比較),反复的jar文件。

    主要代码例如以下:

    package cn.jerryhouse.util.dup_files;
    
    
    import java.io.File;
    
    public abstract class FileProcessor {
    	private long totalFileCount = 0;
    	private long processedFileCount = 0;
    	public void processFiles(File[] dirs) throws Exception {
    		for (File file : dirs) {
    			processFile(file);
    		}
    	}
    
    	public void processFile(File file) throws Exception {
    		if (file.isFile()) {
    			if (isFileAccepted(file)) {
    				handleFile(file);
    				processedFileCount++;
    			}
    			totalFileCount++;
    		} else {
    			File[] files = file.listFiles();
    			for (File fileInDir : files) {
    				processFile(fileInDir);
    			}
    		}
    	}
    
    	protected boolean isFileAccepted(File file) throws Exception {
    		return true;
    	}
    
    	protected abstract void handleFile(File file);
    
    	public long getTotalFileCount() {
    		return totalFileCount;
    	}
    
    	public long getProcessedFileCount() {
    		return processedFileCount;
    	}
    }
    


    package cn.jerryhouse.util.dup_files;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.concurrent.ConcurrentHashMap;
    
    
    public class FileDupFinder extends FileProcessor {
    	protected Map<String, List<String>> fileMap = new ConcurrentHashMap<String, List<String>>();
    	public void analyseResult() {
    		boolean foundDup = false;
    		for (Entry<String, List<String>> entry : fileMap.entrySet()) {
    			List<String> classPathList = entry.getValue();
    			if (classPathList.size() > 1) {
    				System.out.println(" paths:"
    						+ classPathList);
    				foundDup = true;
    			}
    		}
    		if (foundDup == false) {
    			System.out.println("No duplicate file found.");
    		}
    	}
    
    
    	protected void handleFile(final File file) {
    		try {
    			String fileMD5 = FileDigest.getFileMD5(file);
    			try {
    				List<String> list;
    				if (fileMap.get(fileMD5) != null) {
    					list = fileMap.get(fileMD5);
    					list.add(file.getCanonicalPath());
    				} else {
    					list = new LinkedList<String>();
    					list.add(file.getCanonicalPath());
    					fileMap.put(fileMD5, list);
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    
    }
    

    package cn.jerryhouse.util.dup_files;
    
    
    import java.io.File;
    
    public class JarFileDupFinder extends FileDupFinder {
    
    	protected boolean isFileAccepted(final File file) throws Exception
    	{
    		if(file.getCanonicalPath().endsWith(".jar"))
    		{
    			return true;
    		}
    		else
    		{
    			return false;
    		}
    	}
    
    }
    

    package cn.jerryhouse.util.dup_files;
    
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Map.Entry;
    
    import org.objectweb.asm.AnnotationVisitor;
    import org.objectweb.asm.Attribute;
    import org.objectweb.asm.ClassReader;
    import org.objectweb.asm.ClassVisitor;
    import org.objectweb.asm.FieldVisitor;
    import org.objectweb.asm.MethodVisitor;
    
    public class ClassDupFinder extends FileDupFinder {
    
    	protected boolean isFileAccepted(final File file) throws Exception {
    		if (file.getCanonicalPath().endsWith(".class")) {
    			return true;
    		} else {
    			return false;
    		}
    	}
    
    	public void analyseResult() {
    		boolean foundDup = false;
    		for (Entry<String, List<String>> entry : fileMap.entrySet()) {
    			List<String> classPathList = entry.getValue();
    			if (classPathList.size() > 1) {
    				System.out.println("class:" + entry.getKey() + " paths:"
    						+ classPathList);
    				foundDup = true;
    			}
    		}
    		if (foundDup == false) {
    			System.out.println("No duplicate class found.");
    		}
    	}
    
    	protected void handleFile(final File file) {
    		try {
    			String filePath = file.getCanonicalPath();
    			ClassVisitor visitor = new ClassVisitor() {
    				@Override
    				public void visit(int version, int access, String name,
    						String signature, String superName, String[] interfaces) {
    					try {
    						List<String> list;
    						if (fileMap.get(name) != null) {
    							list = fileMap.get(name);
    							list.add(file.getCanonicalPath());
    						} else {
    							list = new LinkedList<String>();
    							list.add(file.getCanonicalPath());
    							fileMap.put(name, list);
    						}
    					} catch (IOException e) {
    						e.printStackTrace();
    					}
    				}
    
    				@Override
    				public void visitSource(String source, String debug) {
    				}
    
    				@Override
    				public void visitOuterClass(String owner, String name,
    						String desc) {
    				}
    
    				@Override
    				public AnnotationVisitor visitAnnotation(String desc,
    						boolean visiable) {
    					return null;
    				}
    
    				@Override
    				public void visitAttribute(Attribute attr) {
    				}
    
    				@Override
    				public void visitInnerClass(String name, String outerName,
    						String innerName, int access) {
    				}
    
    				@Override
    				public FieldVisitor visitField(int access, String name,
    						String desc, String signature, Object value) {
    					return null;
    				}
    
    				@Override
    				public MethodVisitor visitMethod(int access, String name,
    						String desc, String signature, String[] exceptions) {
    					return null;
    				}
    
    				@Override
    				public void visitEnd() {
    				}
    			};
    			ClassReader cr = new ClassReader(new FileInputStream(filePath));
    			cr.accept(visitor, 0);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    
    }
    

    package cn.jerryhouse.util.dup_files;
    
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.math.BigInteger;
    import java.security.MessageDigest;
    import java.util.HashMap;
    import java.util.Map;
    
    public class FileDigest {
    	/**
    	 * 获取单个文件的MD5值
    	 * @param file
    	 */
    	public static String getFileMD5(File file) {
    		if (!file.isFile()) {
    			return null;
    		}
    		MessageDigest digest = null;
    		FileInputStream in = null;
    		byte buffer[] = new byte[1024];
    		int len;
    		try {
    			digest = MessageDigest.getInstance("MD5");
    			in = new FileInputStream(file);
    			while ((len = in.read(buffer, 0, 1024)) != -1) {
    				digest.update(buffer, 0, len);
    			}
    			in.close();
    		} catch (Exception e) {
    			e.printStackTrace();
    			return null;
    		}
    		BigInteger bigInt = new BigInteger(1, digest.digest());
    		return bigInt.toString(16);
    	}
    
    	/**
    	 * 获取文件夹中文件的MD5值
    	 * @param file
    	 * @param listChild 为true时,递归子文件夹中的文件;否则不递归
    	 */
    	public static Map<String, String> getDirMD5(File file, boolean listChild) {
    		if (!file.isDirectory()) {
    			return null;
    		}
    		Map<String, String> map = new HashMap<String, String>();
    		String md5;
    		File files[] = file.listFiles();
    		for (int i = 0; i < files.length; i++) {
    			File f = files[i];
    			if (f.isDirectory() && listChild) {
    				map.putAll(getDirMD5(f, listChild));
    			} else {
    				md5 = getFileMD5(f);
    				if (md5 != null) {
    					map.put(f.getPath(), md5);
    				}
    			}
    		}
    		return map;
    	}
    }

    package cn.jerryhouse.util.dup_files;
    
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileReader;
    
    public abstract class LineReaderProcessor extends FileProcessor {
    	private long totalFileCount = 0;
    	private long processedFileCount = 0;
    	public void processFiles(File[] dirs) throws Exception {
    		for (File file : dirs) {
    			processFile(file);
    		}
    	}
    
    	public void processFile(File file) throws Exception {
    		if (file.isFile()) {
    			if (isFileAccepted(file)) {
    				handleFile(file);
    			}
    		} else {
    			File[] files = file.listFiles();
    			for (File fileInDir : files) {
    				processFile(fileInDir);
    			}
    		}
    	}
    
    	protected boolean isFileAccepted(File file) throws Exception {
    		return true;
    	}
    
    	protected void handleFile(File file)
    	{
    		try {
    			BufferedReader br = new BufferedReader(new FileReader(file));
    			String line;
    			while((line=br.readLine())!=null)
    			{
    				readLine(file,line);
    			}
    			br.close();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	protected abstract void readLine(File file,String line);
    
    	public long getTotalFileCount() {
    		return totalFileCount;
    	}
    
    	public long getProcessedFileCount() {
    		return processedFileCount;
    	}
    }
    

    package cn.jerryhouse.util.dup_files;
    
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.util.UUID;
    
    public abstract class LineUpdateProcessor extends FileProcessor {
    	private long totalFileCount = 0;
    	private long processedFileCount = 0;
    	private String NEW_LINE = System.getProperty("line.separator");
    	public void processFiles(File[] dirs) throws Exception {
    		for (File file : dirs) {
    			processFile(file);
    		}
    	}
    
    	public void processFile(File file) throws Exception {
    		if (file.isFile()) {
    			if (isFileAccepted(file)) {
    				handleFile(file);
    			}
    		} else {
    			File[] files = file.listFiles();
    			for (File fileInDir : files) {
    				processFile(fileInDir);
    			}
    		}
    	}
    
    	protected boolean isFileAccepted(File file) throws Exception {
    		return true;
    	}
    
    	protected void handleFile(File file)
    	{
    		try {
    			BufferedReader br = new BufferedReader(new FileReader(file));
    			File tmpFile = new File(tmpFilePath(file));
    			BufferedWriter bw = new BufferedWriter(new FileWriter(tmpFile));
    			String line;
    			while((line=br.readLine())!=null)
    			{
    				String updatedLine = updateLine(file,line);
    				bw.write(updatedLine+NEW_LINE);
    			}
    			br.close();
    			bw.close();
    			file.delete();
    			tmpFile.renameTo(file);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	
    	private String tmpFilePath(File file)
    	{
    		String dir = file.getParent();
    		String filePath = dir+""+getUniqFileName();
    		return filePath;
    	}
    	
    	private String getUniqFileName()
    	{
    		return UUID.randomUUID().toString();
    	}
    	protected abstract String updateLine(File file,String line);
    
    	public long getTotalFileCount() {
    		return totalFileCount;
    	}
    
    	public long getProcessedFileCount() {
    		return processedFileCount;
    	}
    }
    


    简单測试代码:

    package cn.jerryhouse.util.dup_files.test;
    
    import java.io.File;
    
    import org.junit.Test;
    
    import cn.jerryhouse.util.dup_files.ClassDupFinder;
    import cn.jerryhouse.util.dup_files.FileDupFinder;
    import cn.jerryhouse.util.dup_files.JarFileDupFinder;
    
    public class DupTest {
    
    	@Test
    	public void testJarFiles() {
    		try {
    			File[] files = new File[1];
    			files[0] = new File("E:\workspace\yinxing");
    			JarFileDupFinder dupFinder = new JarFileDupFinder();
    			dupFinder.processFiles(files);
    			dupFinder.analyseResult();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	@Test
    	public void testFileDup() {
    		try {
    			File[] files = new File[1];
    			files[0] = new File("E:\workspace\yinxing");
    			FileDupFinder classDupFinder = new FileDupFinder();
    			classDupFinder.processFiles(files);
    			classDupFinder.analyseResult();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	
    	@Test
    	public void testClassDup() {
    		try {
    			File[] files = new File[1];
    			files[0] = new File("E:\workspace\yinxing");
    			ClassDupFinder classDupFinder = new ClassDupFinder();
    			classDupFinder.processFiles(files);
    			classDupFinder.analyseResult();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    
    
    }
    


    注:依赖jar包asm.jar。


    
  • 相关阅读:
    Spring Boot应用的启动和停止(Spring Boot应用通过start命令启动)
    MySQL注释(转)
    MySQL命令行自动补全表名
    Linux后台运行命令nohub输出pid到文件(转)
    Spring Boot使用MyBatis 3打印SQL的配置
    MySQL常用的七种表类型(转)
    spring-boot-starter-data-redis与spring-boot-starter-redis两个包的区别
    Eclipse的JQuery提示插件-Spket(别试了,没什么效果,且安装设置麻烦)
    MySQL中的数据类型的长度范围和显示宽度(转)
    MySql基本数据类型(转)
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4392259.html
Copyright © 2011-2022 走看看