java查找重复类/jar包/普通文件

来源:互联网 发布:mac的mvn仓库地址 编辑:程序博客网 时间:2024/06/05 17:41

开发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() {@Overridepublic 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();}}@Overridepublic void visitSource(String source, String debug) {}@Overridepublic void visitOuterClass(String owner, String name,String desc) {}@Overridepublic AnnotationVisitor visitAnnotation(String desc,boolean visiable) {return null;}@Overridepublic void visitAttribute(Attribute attr) {}@Overridepublic void visitInnerClass(String name, String outerName,String innerName, int access) {}@Overridepublic FieldVisitor visitField(int access, String name,String desc, String signature, Object value) {return null;}@Overridepublic MethodVisitor visitMethod(int access, String name,String desc, String signature, String[] exceptions) {return null;}@Overridepublic 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 {@Testpublic 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();}}@Testpublic 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();}}@Testpublic 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。



0 0
原创粉丝点击