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。


    
  • 相关阅读:
    BZOJ 1040 (ZJOI 2008) 骑士
    BZOJ 1037 (ZJOI 2008) 生日聚会
    ZJOI 2006 物流运输 bzoj1003
    ZJOI 2006 物流运输 bzoj1003
    NOI2001 炮兵阵地 洛谷2704
    NOI2001 炮兵阵地 洛谷2704
    JLOI 2013 卡牌游戏 bzoj3191
    JLOI 2013 卡牌游戏 bzoj3191
    Noip 2012 day2t1 同余方程
    bzoj 1191 [HNOI2006]超级英雄Hero——二分图匹配
  • 原文地址:https://www.cnblogs.com/jerry1999/p/4175924.html
Copyright © 2011-2022 走看看